二十天刷题计划--双指针

84 阅读1分钟

「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」。

1.题目

删除排序链表中的重复元素 II

给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。

 

示例 1:

输入:head = [1,2,3,3,4,4,5] 输出:[1,2,5]

示例 2:

输入:head = [1,1,1,2,3] 输出:[2,3]

思路

同样是删除重复元素 不过这里第一个元素也要把删除, 因此我们的 当前指针应该指向要比较的两元素的前面,从虚拟头结点开始。 遇到重复元素要记住它的值, 因为后面可能还是重复元素。

然后遇到和记录值相同的元素也要删除

代码

var deleteDuplicates = function(head) {
    if(!head) return null
    let res=new ListNode()
    let count=res
    res.next=head
    while(count.next&&count.next.next){
       if(count.next.val==count.next.next.val){
          let x=count.next.val
          while(count.next&&count.next.val==x){
              count.next=count.next.next
          }
       }else{
           count=count.next
       }
    }
    return res.next
};

2.题目

三数之和

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]]

示例 2:

输入:nums = [] 输出:[]

示例 3:

输入:nums = [0] 输出:[]

思路 利用双指针,思路见代码中的注释

代码

var threeSum = function (nums) {
    const res = []
    const len = nums.length
    nums.sort((a, b) => a - b) // 升序排列

    for (let i = 0; i < len - 2; i++) {
        if (nums[i] === nums[i - 1]) continue // 如果第一位位i有一样的,就直接进位

        let left = i + 1, right = len - 1

        while (left < right) {
            let sum = nums[i] + nums[left] + nums[right]
            if (sum === 0) {
                // 这一行注意
                // 在push的时候,用后++法传入原始值并做双指针+-
                res.push([nums[i], nums[left++], nums[right--]])

                // 判断左右指针是否和上一次一样,一样就跳到下一个去重
                while (nums[left] === nums[left - 1]) left++

                // 看其他人没写right++,其实要写的,因为left变了,right一定要变
                // 如果right还和上次一样,肯定不会sum = 0
                while (nums[right] === nums[right + 1]) right--
            } else {
                // 如果三个数没凑成0,就看是大了还是小了,大了就-right,小了+left
                if (sum > 0) right--
                if (sum < 0) left++
            }
        }
    }
    return res;
};