代码随想录刷题Day6

60 阅读2分钟

链表

  1. 142. 环形链表 II
  • 双指针法 image.png

纯纯数学题。

第一步,判断链表是否有环。一个fast指针一个slow指针,fast指针一次走两步,slow指针走一步,如果没环,slow指针就先走完了,如果有环,fast指针肯定和slow指针相遇在环中,并且此时fast指针多绕了n圈环。

第二步,有环找入口。从头结点到环形入口节点 的节点数为x。 环形入口节点到 fast指针与slow指针相遇节点 节点数为y。 从相遇节点 再到环形入口节点节点数为 z。

fast指针走的距离为 x + y + n (y + z),slow指针走的距离为x + y,因为fast指针是一步走两个节点,slow指针一步走一个节点, 所以fast走的距离是slow的两倍可得到等式:(x + y) * 2 = x + y + n (y + z) 化简得到x + y = n (y + z)

要找环形的入口,即求x可得x = n (y + z) - y

整理公式之后为如下公式:x = (n - 1) (y + z) + zy + z就是环节点数,n=1时,x = z解题思路就是从头结点出发一个指针,从相遇节点也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点。n>1时,其实效果一样,脑内可以过一遍。

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast =head;//快指针
        ListNode slow =head;//慢指针
        while(fast!=null&&fast.next!=null){//快指针能走得完则无环
            fast=fast.next.next;//快指针走两步
            slow=slow.next;//慢指针走一步
            if(fast==slow){//第一次相遇,则说明有环
                fast=head;//重新定义了一个头结点,
                while(fast!=slow){//再次相遇点就是入环点
                    fast=fast.next;
                    slow=slow.next;
                }
                return fast;
            }
        }
        return null;
    }
}

哈希表

  1. 1. 两数之和
  • 方法一:暴力
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] arr=new int[2];
        for(int i=0;i<nums.length-1;i++){
            for(int j=i+1;j<nums.length;j++){
                if(nums[i]+nums[j]==target){
                    arr[0]=i;arr[1]=j;
                    return arr;
                }
            }
        }
        return null;
    }
}
  • 方法二:哈希表

遍历数组 nums,i 为当前下标,每个值都判断map中是否存在 target-nums[i] 的 key 值

如果存在则找到了两个值,如果不存在则将当前的 (nums[i],i) 存入 map 中,继续遍历直到找到为止

leetcode.cn/problems/tw…

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map=new HashMap<>();//哈希表里,key是元素,value是下标
        for(int i=0;i<nums.length;i++){
            if(map.containsKey(target-nums[i])){//查看map里面是否存在 target-nums[i] 的 key 值
                int[] arr={map.get(target-nums[i]), i};//存在就返回value(value存的是数组下标),注意这个顺序,当前是i,另一个元素的下标必定存在前面
                return arr;
            }
            map.put(nums[i],i);//没有就把当前num[i]存入map
        }
        return null;
    }
}