Leedcode刷题技巧及方法总结(学习笔记,建议收藏,持续更新)

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 622

4.对于两头大中间小的数组排序,可以开辟额外空间,用双指针比较最左或最右元素放入  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 19

16.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) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值