刷题笔记(八)--双指针:两数之和以及延伸

系列文章目录

刷题笔记(一)–数组类型:二分法
刷题笔记(二)–数组类型:双指针法
刷题笔记(三)–数组类型:滑动窗口
刷题笔记(四)–数组类型:模拟
刷题笔记(五)–链表类型:基础题目以及操作
刷题笔记(六)–哈希表:基础题目和思想
刷题笔记(七)–字符串:经典题目

题录

这里在正式引申之前说一下,双指针法是一种应用很广的方法,像我们前面的数组,链表,字符串等等,很多问题都是使用双指针法来解决。具体的可以看我之前的博客,这篇博客主要就是对两数之和问题做一个拓展。

两数之和

题目链接如下:

两数之和

截屏如下:
在这里插入图片描述
是不是很眼熟,之前我们是不是做过对应的题目?第一种解法就是暴力遍历,第二种就是用一个哈希表来记录映射关系。

import java.util.HashMap;

public class 两数之和 {
    public int[] twoSum(int[] nums, int target) {
        HashMap<Integer,Integer> hashMap = new HashMap();
        for (int i = 0; i < nums.length; i++) {
            if(hashMap.containsKey(target-nums[i])){
                return new int[]{i,hashMap.get(target-nums[i])};
            }
            hashMap.put(nums[i],i);
        }
        return null;
    }
}

三数之和

题目链接如下:

15. 三数之和

题目截屏如下:
在这里插入图片描述
这个题目是很有意思的,因为三数之和,总体思路就是在二数之和的基础上做一个延伸,也就是在确定一个数的情况下,寻找另外两数之和等于0 - (当前已确定数)。但是具体细节还是要仔细敲定一下的。也幸好不是返回下标,不然更麻烦。

public class 三数之和 {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> list = new ArrayList<>();
        for (int i = 0; i < nums.length - 2; i++) {//如果这个时候就剩下两个元素就没有必要再遍历了
            //我们是从前往后遍历的,而且是从小到大的,这就意味着当前数组下标元素是最小的,如果最小的都大于0,那就没有必要再继续遍历了
            if(nums[i] > 0){
                break;
            }
            if(i > 0 && nums[i] == nums[i - 1]){
                continue;//如果当前元素和上一个元素相同,那就没有必要再来一次,这也是为了防止有重复的
            }
            int left = i + 1;
            int right = nums.length - 1;
            while(left < right){
                int sum = nums[i] + nums[left] + nums[right];
                if(sum > 0){
                    right--;
                }else if(sum < 0){
                    left++;
                }else{
                    list.add(Arrays.asList(nums[i],nums[left],nums[right]));
                    //这里的两个while循环是为了祛除相同元素的,比如说[-3,0,0,3,3]这种的
                    while(left < right && nums[left] == nums[left + 1]){
                        left++;
                    }
                    while(left < right && nums[right] == nums[right - 1]){
                        right--;
                    }
                    left++;
                    right--;
                }
            }
        }
        return list;
    }
}

四数之和

题目链接如下:

18. 四数之和

题目截屏如下:
在这里插入图片描述
四数之和和三数之和的主要区别就是在外面套了一层循环。当然这是主要的,还有就是一些细节的处理。

public class 四数之和 {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);
        List<List<Integer>> list = new ArrayList<>();
        for(int i = 0;i < nums.length - 3;i++){//如果说当前数组元素只剩三个那就没有必要再继续找了
            if(i > 0 && nums[i] == nums[i - 1]){//保证元素不相同
                continue;
            }
            for(int j = i + 1;j < nums.length - 2;j++){//如果当前就只剩两个元素就没有必要在继续找了
                if(j > i + 1 && nums[j] == nums[j - 1]){//保证元素不相同
                    continue;
                }
                int left = j + 1;
                int right = nums.length - 1;
                while(left < right){
                    int sum = nums[i] + nums[j] + nums[left] + nums[right];
                    if(sum > target){
                        right--;
                    }else if(sum < target){
                        left++;
                    }else{
                        list.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));
                        //保证数组元素不相同
                        while(left < right && nums[left] == nums[left + 1]){
                            left++;
                        }
                        while(left < right && nums[right] == nums[right - 1]){
                            right--;
                        }
                        left++;
                        right--;
                    }
                }
            }
        }
        return list;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值