leetcode个人整理

1 Linked List

P21. Merge Two Sorted Lists
关键点

Linked List的初始化和更新(new 和 list.next的关系)

//定义一个链表的头和尾,并都初始化为null
ListNode head=null,tail=null;
//再循环里需要每次更新时,进行如下操作
if(head==null){
     head=new ListNode(nval);
     tail=head;
}else{
     tail.next=new ListNode(nval);
     tail=tail.next;
}
易错点

循环条件是||而不是&&
可以这么想:停止循环的时候是两个list都为空,才不连了
所以下次想不清楚循环条件的时候可以反过来想停止循环的条件

while(l1!=null||l2!=null)
P19. Remove Nth Node From End of List
关键点
  1. 不知道Linked List长度的情况下,很难找到倒数第N个元素,所以一个思路就是先得到长度,再计算出要删的点是从头数第几个,将它前后的ListNode相连
  2. 要先设置一个空节点dummy,为了处理删掉的点是head的情况(所以最后return的是dummy.next而不是head)
易错点

统计sum(总共几个ListNode)和计算是从头数第几个,用一个栗子试试看。

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy=new ListNode(0);
        dummy.next=head;
        ListNode first=head;
        int sum=0;
        while(first!=null){
            first=first.next;
            sum++;
        }
        System.out.println(sum);
        sum=sum-n;
        first=dummy;
        while(sum>0){
            first=first.next;
            sum--;
        }
        first.next=first.next.next;
        return dummy.next;
    }
}
P24. Swap Nodes in Pairs
关键点
  1. 设置一个dummy空节点,来避免head移动影响结果的情况

  2. 比如1->2->3->4 先考虑交换前2个数,然后交换后2个数基本和之前一致
    图解见https://blog.csdn.net/qq_34269988/article/details/89492526?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
    步骤
    1 断开1->2,连接1->3
    2 断开2->3, 连接 2 ->1
    3 断开dummy->1,连接dummy->2
    这个过程中dummy,1,2变量分别对应pre, first, second

  3. 之后变成dummy->2->1->3->4, 交换3,4时 pre移动到1,即代码里的first

易错点

while的边界条件:要交换的first和second都存在,只存在first或者都不存在就不用交换

code
class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummy= new ListNode(0);
        dummy.next=head;
        ListNode pre=dummy;
        while(pre.next!=null&&pre.next.next!=null){
            ListNode first=pre.next;
            ListNode second=pre.next.next;
            first.next=second.next;
            second.next=first;
            pre.next=second;
            pre=first;
        }
        return dummy.next;       
    }
}

2 Two Pointers

P26. Remove Duplicates from Sorted Array
关键点

题目比较简单,但有2个比较特殊的地方

  1. 不能使用别的数组,所以所有的操作都在输入数组实现,JAVA并不方便改变数组大小,所以最后的结果其实是数组的一部分
  2. 最后的返回值很巧妙,返回的是int类型表示数组长度,结果却是一个数组(相当于初始位置根据数组长度寻址)
易错点

i 表示现在修改的位置,所以返回长度时要+1

P27. Remove Element
易错点

为什么本题最后返回的是i而不是i+1
因为每次给nums[i]赋值之后,都给i+1,所以最后返回的 i 是现在修改的位置+1,即最后要返回的长度。

public int removeElement(int[] nums, int val) {
    int i = 0;
    for (int j = 0; j < nums.length; j++) {
        if (nums[j] != val) {
            nums[i] = nums[j];
            i++;
        }
    }
    return i;
}

3 Binary Search

P29. Divide Two Integers
关键点
  1. 根据被除数和除数的正负决定结果的正负,然后都转化为正数计算(想到)
  2. 如果每次使用lef-divisor,如果dividend较大,会导致超时
    解决方法:每次不是-divisor,而是利用二进制,比如29/8=3,3=2+1
    29(lef)除以8,8(div)左移一位,16(t)小于29,再左移一位,超过29(跳出while (lef >= (t << 1))循环),于是29(lef)减去之前的16,res加上2(即p的值,左移一位等于扩大两倍)。第二次循环时因为此时的13小于8的二倍,故加上1,整个循环结束,最终结果为2+1=3,符合要求。
易错点
  • 这个问题的边界条件:[-2的31次,2的31次-1],所以如果直接使用int ,将负数dividend取绝对值时会出错,所以先把dividend类型变成长整型,再取绝对值
  • 最后对结果做一个判断,如果越界,返回特殊值;不然返回转换回int的值
关键代码
		long lef=Math.abs((long)dividend);
        long div=Math.abs((long)divisor);
        while (lef >= div) {
			long t = div, p = 1;
			while (lef >= (t << 1)) {
				p <<= 1;
				t <<= 1;
			}
			res += p;
			lef -= t;
		}

4 Math

周赛 P1390. 四因数
关键点
  1. 一个数有四个因数分为两种情况:1 这个数能分解成2个素数的乘积(这两个素数不相等) 2 这个数是素数的立方数
  2. 素数筛子:完成第一点判断的关键是得到1到max(输入数组nums的最大值)-1中的全部素数,应用普通循环判断容易超时,使用素数筛子来提高程序运行效率(具体思路见code注释)
易错点

举一些特别栗子来说明

  1. 9,因数{1,3,9},所以分解成2素数的积后,还要判断不相等
  2. 8,因数{1,2,4,8},8=2 * 4,4不是素数,但4=2 * 2,不会增加新因数,即8是2的立方数,满足四因数条件
代码和注释
class Solution {
    public int sumFourDivisors(int[] nums) {
        if(nums.length==0)
            return 0;
        Arrays.sort(nums);
        //获取最大的数mnum,1到mnum-1即为生成素数的范围
        int mnum=nums[nums.length-1];
        int res=0;
        //该数组表示是否为素数,初始全为1(当全是素数),后续把一些筛掉变成0
        int[] isPrim=new int[mnum];
        for(int i=0;i<mnum;i++)
            isPrim[i]=1;
        //素数筛子
        for(int i=2;i*i<mnum;i++){
            for(int j=i*i;j<mnum;j+=i){
                isPrim[j]=0;
            }
        }
        for(int num:nums){
            for(int i=2;i<=Math.sqrt(num);i++){
                if(isPrim[i]==0) continue;//合数则跳过
                if(num%i==0){
                    //对应关键点1中的两种情况
                    if((isPrim[num/i]==1&&num!=i*i)||num==i*i*i){
                        res+=1+num+i+num/i;    
                    }
                    //break的解释:一个数等于两个因数的积时,就能判断是否是四因数
                    break;
                }   
            }
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值