LeetCode三数之和

解决三数之和使用哈希表的方法比较复杂,同时也体现在去重的重点上,所以推荐使用排序+双指针的方法,本文中这题运用到的就是左右双指针的方法。

双指针常见的几种方式包括:

1. 快慢指针:快指针比慢指针快,两个指针从同一起点开始,快指针每次移动两步,慢指针每次移动一步,常用于链表的问题中。

2. 左右指针:左指针和右指针从两端开始,向中间移动,通常用于数组的问题中。

3. 对撞指针:在左右指针的基础上,左指针向右移动时,右指针向左移动,因此也叫双向指针。

4. 滑动窗口:指定一个窗口大小,在滑动窗口过程中不断移动左右指针,通常用于字符串和数组的问题中。

5. 三指针:在快慢指针的基础上,加上第三个指针用于标记某个位置,例如链表中的倒数第n个节点问题。

6. 二分指针:也称二分查找,常用于有序数组的查找问题中,通过不断缩小区间并移动左右指针来寻找目标值。

 

 

 首先对数组进行排序

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(nums);

 使用一个for循环,但要注意一定要从0的位置开始遍历,因为如果nums[i]>0,那么就会直接返回结果,同时对i去重,在这里面nums[i]==nums[i-1]和nums[i]==nums[i+1]从本质上来说是有区别的,nums[i+1]表示前面的元素和后面要相同,但同时也产生了一个问题,例如:[-1,-1,2],其中nums[i]=-1,nums[i+1]=-1,这就不符合三数之和的判断条件i!=j,j!=k,k!=i的条件,所以使用nums[i]=nums[i-1]判断前一个数和本身的数是否相等就更加符合条件

nums[i]==nums[i+1]

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

            if (i > 0 && nums[i] == nums[i - 1]) {  
                continue;
            }

 使用一个while循环,其中right>left,不能等于,因为这是一个左右双指针,当两边指针移动到中间时一定要保证右边大于左边,然后定义一个整数sum,当sum>0时,right下标要向左边减少,因为sum的值在增大,只有将right下标的值减小,才能使sum=0,同理left++也一样。

int left = i + 1;
            int right = nums.length - 1;
            while (right > left) {
                int sum = nums[i] + nums[left] + nums[right];
                if (sum > 0) {
                    right--;
                } else if (sum < 0) {
                    left++;
                } else {
                    result.add(Arrays.asList(nums[i], nums[left], nums[right]));

同时在对sum进行判断的同时也要在对left和right进行去重,首先要满足right>left,其次也要同时满足nums[right]=nums[right-1],如果right前一个元素和它相等那么就会跳过它去right-2的元素,同理left也一样。

 

                    while (right > left && nums[right] == nums[right - 1]) right--;
                    while (right > left && nums[left] == nums[left + 1]) left++;
                    
                    right--; 
                    left++;

 最后源码如下:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(nums);
        // a = nums[i], b = nums[left], c = nums[right]
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > 0) { 
                return result;
            }

            if (i > 0 && nums[i] == nums[i - 1]) {  
                continue;
            }

            int left = i + 1;
            int right = nums.length - 1;
            while (right > left) {
                int sum = nums[i] + nums[left] + nums[right];
                if (sum > 0) {
                    right--;
                } else if (sum < 0) {
                    left++;
                } else {
                    result.add(Arrays.asList(nums[i], nums[left], nums[right]));
                    while (right > left && nums[right] == nums[right - 1]) right--;
                    while (right > left && nums[left] == nums[left + 1]) left++;
                    
                    right--; 
                    left++;
                }
            }
        }
        return result;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值