day73【代码随想录】二刷链表


前言

1、等差子数组
2、寻找重复数
3、缺失的第一个正数
4、等差子数组


一、环形链表||(力扣142)

在这里插入图片描述
分析:
快慢指针 快指针一直一次走两步 慢指针一次走一步
先判断是否有环 快慢指针是否会相等
在有环的基础上,去找入口位置

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;

        while(fast!=null && fast.next!=null){
            //先判断是否有环
            slow = slow.next;
            fast = fast.next.next;
            if(slow==fast){//有环
                ListNode index1 = fast;
                ListNode index2 = head;
                //找入口 
                while(index1!=index2){
                    index1 = index1.next;
                    index2 = index2.next;
                }
                return index1;
            }
        }
        return null;
    }
}

二、寻找重复数(力扣287)

在这里插入图片描述
分析:将其转化为环形链表||
大佬题解

class Solution {
    public int findDuplicate(int[] nums) {
        int res = 0;
        int slow = 0;
        int fast = 0;
        slow = nums[slow];
        fast = nums[nums[fast]];
        //由题意得一定会出现环
        while(slow!=fast){
            slow = nums[slow];
            fast = nums[nums[fast]];
        }
        //此时slow和fast相遇
        //寻找相遇的入口
        int index1 = 0;
        int index2 = slow;
        while(index1!=index2){
            index1 = nums[index1];
            index2 = nums[index2];
        }
        res = index1;
        return res;
    }
}

三、缺失的第一个正数(力扣41)

在这里插入图片描述
分析:

如果没有额外的时空复杂度要求,那么就很容易实现:
将数组所有的数放入哈希表,随后从 1开始依次枚举正整数,并判断其是否在哈希表中;
我们可以从 1 开始依次枚举正整数,并遍历数组,判断其是否在数组中。
如果数组的长度为 N,那么第一种做法的时间复杂度为 O(N),空间复杂度为 O(N);第二种做法的时间复杂度为 O(N2),空间复杂度为 O(1)。但它们都不满足时间复杂度为 O(N) 且空间复杂度为 O(1)。

力扣题解

在这里插入图片描述
==注意:==特别需要注意第二步:

    for(int i=0;i<nums.length;i++){
        if(nums[i]<=n && nums[i]>0){
            nums[nums[i]-1] = -1*nums[nums[i]-1];
        }
    }

这样写的问题所在在于: 例如 3,4,-1,1
经过第一步后变为:3,4,5,1;
按上述代码执行第二步后:3,4,-5,-1;
问题在于变为-1后 3无法标记为-3, 因此要用取绝对值的方式

    for(int i=0;i<nums.length;i++){
        int num = Math.abs(nums[i]);
        if(num<=n){
            nums[num-1] = -Math.abs(nums[num-1]);
        }
    }
class Solution {
public int firstMissingPositive(int[] nums) {
        int n = nums.length;
        for(int i=0;i<nums.length;i++){
            if(nums[i]<=0){
                nums[i] = n+1;
            }
        }
        for(int i=0;i<nums.length;i++){
            int num = Math.abs(nums[i]);
            if(num<=n){
                nums[num-1] = -Math.abs(nums[num-1]);
            }
        }
        for(int i=0;i<n;i++){
            if(nums[i]>0){
                return i+1;
            }
        }
        return n+1;
    }
}

每日一题day73:等差子数组(力扣1630)

在这里插入图片描述
分析:
简单模拟 数据量不大 暴力求解不会超时
截取每一段数组 排序 依次判断差值是否相等

class Solution {
    public List<Boolean> checkArithmeticSubarrays(int[] nums, int[] l, int[] r) {
        //
        int length = l.length;
        Boolean[] res = new Boolean[length];
        Arrays.fill(res,true);

        for(int i=0;i<length;i++){
            int left = l[i];
            int right = r[i];
            int[] curArray = Arrays.copyOfRange(nums,left,right+1);
            Arrays.sort(curArray);
            int gap = curArray[1]-curArray[0];
            for(int j=2;j<curArray.length;j++){
                int diff = curArray[j]-curArray[j-1];
                if(diff!=gap){
                    res[i] = false;
                    break;
                }
            }
        }
        return Arrays.asList(res);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值