链接列表的中间值:
- 测试用例1: 创建链表
[1, 2, 3, 4, 5]
,调用middleNode
,预期返回值是 3。- 测试用例2: 创建链表
[1, 2, 3, 4, 5, 6]
,调用middleNode
,预期返回值是 3。
判断长度,然后length/2
struct ListNode* middleNode(struct ListNode* head){
int length = 0;
for(struct ListNode* curr = head;curr != NULL;curr = curr ->next){
length++;
}
//开始计数走length/2步
struct ListNode* result = head;
for (int i = 0; i < length/2; i++){
result = result->next;
}
return result;
}
使用快慢指针:
struct ListNode* fast = head->next->next;
struct ListNode* low = head->next;
当使用快慢指针的时候,当fast->next==NULL;说明fast已经走到末尾了,但是low刚刚好是fast的一半,因此就可以返回low指针所指的值
但是这里面有一个坑。 不仅要知道 fast != NULL 在 fast的执行途中由于fast是一次跳两个 即 fast->next->next,因此需要保证 fast->next != NULL
代码如下:
struct ListNode* middleNode(struct ListNode* head){
struct ListNode* fast = head;
struct ListNode* slow = head;
while (fast != NULL && fast ->next != NULL){
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
Backspace String Compare:
给定两个字符串
S
和T
,你需要模拟按键操作,即在每个字符串中,#
表示删除前一个字符。返回两个字符串是否相等。
- 你需要实现一个函数
backspaceCompare(S, T)
,该函数返回True
或False
,表示处理后的两个字符串是否相等。示例1:
Copy Code
输入:S = "ab#c", T = "ad#c" 输出:true 解释:S 和 T 都会变成 "ac"
示例2:
Copy Code
输入:S = "ab##", T = "c#d#" 输出:true 解释:S 和 T 都会变成 ""
申请一个数组:
新申请一个数组,然后遍历,如果原数组元素不为#则就复制到新数组,如果原数组为#,就先j--,再把 '\0'复制到该下标的上一位元素作为删除操作
void process(char* result_S,const char* S){
int len_S = strlen(S);
int j = 0;
for(int i = 0;i < len_S;i++){
if (S[i] != '#'){
result_S[j] = S[i];
j++;
} else{
if(j > 0){
j--;
}
}
}
result_S[j] = '\0';
}
bool backspaceCompare(char* S,char* T){
int len_S = strlen(S);
char result_S[len_S + 1];
process(result_S, S);
int len_T = strlen(T);
char result_T[len_T + 1];
process(result_T, T);
return strcmp(result_S,result_T) == 0;
}
直接修改原数组
char* process(char* str){
int len_str = strlen(str);
int j = 0;
for (int i = 0;i < len_str;i++){
if(str[i] != '#'){
str[j] = str[i];
j++;
}
else{
if (j > 0){
j--;
}
}
}
str[j] = '\0';
return str;
}
bool backspaceCompare(char* S,char* T){
return strcmp(process(S),process(T)) == 0;
}
简单的Stack结构体创建:
创建结构体后完成一些操作。
注意:
malloc和realloc后
报错:
obj->data = realloc(obj->data,sizeof(int) * (obj->size + 1));
不报错:
obj->data = (int *)realloc(obj->data,sizeof(int) * (obj->size + 1));
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <bits/stdc++.h>
#include <stack>
typedef struct{
int* data;
int size;
} MinStack;
MinStack* minStackCreate() {
MinStack* s = (MinStack*)malloc(sizeof(MinStack));
s->data = NULL;
s->size = 0;
return s;
}
void minStackPush(MinStack* obj,int x){
obj->data = (int *)realloc(obj->data,sizeof(int) * (obj->size + 1));
obj->data[obj->size] = x;
obj->size++;
}
void minStackPop(MinStack* obj){
obj->size--;
}
int minStackTop(MinStack* obj){
return obj->data[obj->size-1];
}
int minStackGetMin(MinStack* obj){
int min = obj->data[0];
for (int i = 0; i < obj->size; i++){
if (obj->data[i] < min)
{
min = obj->data[i];
}
}
return min;
}
void minStackFree(MinStack* obj){
free(obj->data);
free(obj);
}
int main() {
MinStack* stack = minStackCreate();
// 测试 push 操作
minStackPush(stack, 10);
minStackPush(stack, 20);
minStackPush(stack, 5);
minStackPush(stack, 30);
// 测试 top 操作
printf("Top of stack: %d\n", minStackTop(stack)); // 30
}
二叉树的直径:
给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。
注意:两结点之间的路径长度是以它们之间边的数目表示。
题意是给一个二叉树,找二叉树里面的最大直径。最大直径的定义是任意两个 node 之间的最大距离。注意这个最大距离很有可能不经过根节点,如下图例子,最大直径是从 9 到 8,摘自LC中文网
struct TreeNode{
int val;
struct TreeNode *left;
struct TreeNode *right;
}
递归的思想:
/*
// 没有 typedef
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
struct TreeNode *root; // 使用时要写 struct TreeNode
// 使用 typedef
typedef struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
TreeNode *root; // 使用时只需要写 TreeNode
*/
#include <stdio.h>
#include <bits/stdc++.h>
typedef struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
int maxDepth(struct TreeNode* root){
if (root == NULL) return 0;
int leftMax = maxDepth(root->left);
int rightMax = maxDepth(root->right);
if (leftMax > rightMax){
return leftMax + 1;
}
return rightMax + 1;
}
int diameterOfBinaryTree(struct TreeNode* root){
if (root == NULL) return 0;
//一、最长的路径会通过root
int middle = maxDepth(root->left) + maxDepth(root->right);
//二、最长的路径不会通过root
//全在左边
int left = diameterOfBinaryTree(root->left);
//全在右边
int right = diameterOfBinaryTree(root->right);
int max = middle;
if (left > max)
{
max = left;
}
if (right > max)
{
max = right;
}
return max;
}
最后石头的重量:
有一个石头集合,每个石头都有一个正整数重量值。每次,我们选择两块最重的岩石并将它们粉碎在一起。假设石头的重量为x和y,x <= y。粉碎的结果是:
如果x == y,两块石头都被完全粉碎;
如果x != y,重量为x的石头被完全粉碎,重量为y的石头具有新的重量y-x。
最后,剩下最多1块石头。返回这块石头的重量(如果没有留下石头,则返回0)。
例如:
输入:[2,7,4,1,8,1]
输出:1
说明:
我们将7和8结合起来得到1,所以数组转换为[2,4,1,1,1],
然后我们将2和4结合起来得到2,所以数组转换为[2,1,1,1],
然后我们将2和1结合起来得到1,所以数组转换为[1,1,1],
然后我们将1和1组合起来得到0,所以数组转换为[1],那就是最后一块石头的重量值。注意:
1 <= stones.length <= 30
1 <= stones[i] <= 1000
遍历:
最后数组的值就 y = 0 x = 0 返回0
y>0 x = 0 返回y
y!=0 && x!=0 继续比较
int extractMax(int* stones,int stonesSize){
int max = stones[0];
for (int i = 0; i < stonesSize; i++){
if (stones[i > max]){
max = stones[i];
}
}
for (int i = 0; i < stonesSize; i++){
if (stones[i] == max){
stones[i] = 0;
break;
}
}
return max;
}
void insert(int* stones,int stonesSize,int value){
for (int i = 0; i < stonesSize; i++){
if (stones[i] == 0){
stones[i] = value;
return;
}
}
}
int lastStoneWeight(int* stones,int stonesSize){
while (true){
int y = extractMax(stones,stonesSize);
int x = extractMax(stones,stonesSize);
if (x == 0){
return y;
}
if (x != y){
insert(stones,stonesSize,y - x);
}
}
return 0;
}
奇数在前,偶数在后:
int v[10] = {1, 4, 5, 2, 3, 8, 6, 9, 7, 10};
- 所有奇数将排在前面。
- 奇数内部按原始顺序排布。
- 所有偶数将排在后面。
- 偶数内部按原始顺序排布。
所以输出的数组将是:
1 5 3 9 7 4 2 8 6 10
。
#include <stdio.h>
#include <stdlib.h>
int cmp(const void* a,const void* b){
int va = *(const int*)a;
int vb = *(const int*)b;
//va,vb同为奇数的话,return 0 不需要改变
if (va % 2 == 1 && vb % 2 == 1){
return 0; //不改变
}
//va为奇数,vb为偶数,return -1 让va排在vb前面
if (va % 2 == 1 && vb % 2 ==0){
return -1;
}
//va为偶数,vb为奇数,return -1 让vb排在va前面
if (va % 2 == 0 && vb % 2 ==1){
return 1;
}
//如果 va 是偶数,vb 是奇数,返回 1,让 vb 排在 va 前面
if (va % 2 == 0 && vb % 2 == 0) {
return 0;
}
//如果 va 和 vb 都是偶数,返回 0,不改变顺序
return 0;
}
int main() {
int v[10] = {1,4,5,2,3,8,6,9,7,10};
qsort(v, 10, sizeof(int), cmp);
for (int i = 0; i < 10; i++){
printf("%d ",v[i]);
}
}