1. int mid=left + (right - left)/2 leedcode 278
有效防止mid溢出2.想要更改链表链接顺序,可以考虑使用guard拆解链接 leecode 138
3.对于数组下标循环
右循环:(cur+size)%size 在0~size间循环 用于cur++
求现在的前一个位置:(cur-1+size)%size leedcode 6224.对于两头大中间小的数组排序,可以开辟额外空间,用双指针比较最左或最右元素放入 leedcode 977
5.求链表中间位置,用快慢指针
7.求阶乘k的0
int count=0;
while(n/5)
{
count+=n/5;
n/=5;
}leedcode 172
8.对于有next=cur->next的,将其放入while(cur)循环中,防止其不存在的情形
9.双指针问题多需要开辟出额外相同空间 leedcode 88
10.题中若给定非降序数组可以多考虑下二分法 牛客JZ23
11.判断两个数字有几个比特位不相同,只需按位异或后求1的个数 leedcode 面试题 05.06
12.要想遍历一遍数组求出最大值和次大值,不能用下标去记录,因为你去比较刚开始一定是 maxi=smaxi=0
但这就会产生一个问题,如果arr[0]是最大值,你需要找出arr[maxi]>arr[i]>arr[smaxi],这是不可能的因为你只能满足第一个条件
所以必须采用值进行记录 max=x smax=z x和z必须要小于数组每一个值,这样才可能达到一次遍历两个数的目的 去用另外变量记录下标13.给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。leedcode 149
一个数组中有一个数字出现次数大于n/2,从第 0 个字符开始,假设它就是最多的那个数字,遇到相同的数字则计数+1 ,遇到不同的则计数-1
其实就是互相消耗,等到计数为 0 的时候,表示本次互拼完毕,从下一个字符重新开始互拼,但是归根结底出现次数大于n/2 的这个数字数量更多
因此也是最后保留的字符。
示例: 23335首先从字符 2 开始计数 1 ,遇到 3 ,不同则-1 ,互拼消耗 重新从剩下的"335" 开始的过程,这时
候保存的字符为 3 ,遇到 3 则计数+1 , 遇到5则计数-1 ,在计数不为 0 时,走到末尾保存的字符就是个数超过n/2的字符14.一个数的因数不会超过自己本身的1/2 如28 因数有 1 2 7 14 28(除了最特殊的这个) 牛客HJ56
15.要找到链表中倒数第n个节点,可以用快慢指针,让一个指针超前n个,再同时遍历,停下的节点即为所求的节点
如果要删除此元素,我们可以补一个guard,这样停下来是是要删除节点的前驱节点 leedcode 1916.0和任何数异或数不变,两相同数异或值为0 牛客KS33
17.0 Leedcode 1823约瑟夫环 队列思想
#include<stdio.h> #include<stdlib.h> typedef struct QueueNode { int val; struct QueueNode* next; }QNode; int main(void) { int n,m; scanf("%d%d",&n,&m); QNode* head=NULL; QNode* tail=NULL; for(int i=1;i<=n;i++) { if(head==NULL) { QNode* newnode=(QNode*)malloc(sizeof(QNode)); newnode->val=i; newnode->next=NULL; head=tail=newnode; } else { QNode* newnode=(QNode*)malloc(sizeof(QNode)); newnode->val=i; newnode->next=NULL; tail->next=newnode; tail=newnode; } } for(int j=0;j<n-1;j++) { for(int i=0;i<m;i++) { if(i==m-1) { QNode* next=head->next; free(head); head=next; } else { QNode* next=head->next; tail->next=head; tail=head; head=next; } } } printf("%d",head->val); return 0; }
没有必要去真的写出队列,仅仅只是用头尾指针进行模拟。
18.如何判断一棵树的叶子是左叶子?(Leedcode 404)
我们没有办法单从叶子来进行区分,应该借助其父节点。
对于父节点来说,左叶子节点就是 父节点的左孩子,且孩子的左右节点均为空
因此对于这道求树左叶子的和也就很容易可以写出如下代码:
int sumOfLeftLeaves(struct TreeNode* root) { if(root==NULL) return 0; if(root->left!=NULL&&root->left->left==NULL&&root->left->right==NULL) return root->left->val+sumOfLeftLeaves(root->right); return sumOfLeftLeaves(root->left)+sumOfLeftLeaves(root->right); }
19.Leedcode中不允许对int类型的数做左移31位的操作。
可将其转为size_t, 则操作可以执行
20.对于两个单链表的穿插,如A->C,B->D->E,要更改为A->B->C->D->E (Leedcode 143)
一定是将少的穿插在多的里面,然后以少的作为循环条件。
21.对于快慢指针停下的位置,偶数位停在中点后一个节点,奇数位停在中间节点。(Leedcode 143)
22.对于从中点后逆置的链表,其前一位的后一位所连为空节点。 (Leedcode 234)
1->2->2->1
链表逆置后为1->2 1->2但此时前一个链表中2的下一位是第二个链表的2,他的下一个节点为空,所以循环终止条件可以为while(cur1->next)
23.对于506,可以以循环角度解读为0*10+5(A) A*10+0(B)B*10+6 Leedcode1290
同理,对于二进制101 为0*2+1(A)A*2+0(B)B*2+1(C)