【两数之和】【三数之和】

1.题目描述

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9

所以返回 [0, 1]

2.解题思路

依次遍历数组里面的数值

  • (1)用一个hashmap存储(target-nums[i],索引位置)

  • (2)如果下一次出现nums[i],说明找到了。直接将她的坐标跟之前存储的坐标存到结果。

    如示例:nums = [2, 7, 11, 15], target = 9

    i = 0 时, map存入(7,0)

    i= 1时,发现map.get(num[i]) = map.get(7)!=null, 存在,即找到了,直接将map.get(7) =0,i = 1,这两个值存到结果res里面返回。

3.代码

class Solution {
          public int[] twoSum(int[] nums, int target) {
        //用一个hashmap进行存储【key = target-nums[i],value = 索引位置】
        Map<Integer, Integer> map = new HashMap();
        int res[] = new int[2];
        for (int i = 0; i < nums.length; i++) {
            //此时只要寻找map里面是否有nums[i],即找到两数之和
            //map.get(nums[i])指向的是(target-nums[i])那个数的索引,i指向的是nums[i]的索引
            if (map.get(nums[i]) != null) {
                res = new int[]{map.get(nums[i]), i};
                return res;
            } else {
                map.put(target - nums[i], i);
            }
        }
        return res;
    }
 }

4.我的提交记录

两数之和

1.题目描述:

 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c =0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如,
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
  [
   [-1, 0, 1],
   [-1, -1, 2]
  ]

2.解题思路

  • 首先按升序排序;然后定义下标变量i,j,k,因为是三元组,所以要三个变量如果简单的遍历,那么跟是否有序没有关系,其时间复杂度将达到O(n^3)。
  • 仔细想想:如果当前选择了a、b、c三个数,如果其和小于目标target,那么需要将其中一个数用更大的数替换;反之亦然。但究竟替换三个数中的哪个数?无法确定就只能先固定两个变量,让其第三个变化(替换)。
  • 一种办法是:固定前两个数i,j,然后让k在一个范围中二分变化(二分查找思想)

3.代码

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> results = new ArrayList<>();
        // 升序排序
        Arrays.sort(nums);
        // 用于存储记录过的target值
        Set<Integer> targetSet = new HashSet<>();
        for (int index = 0; index <= nums.length - 2; index++) {
            // 依次固定target
            int target = -1 * nums[index];
            // target记录过则直接跳过
            if (targetSet.contains(target)) {
                continue;
            } else {
                targetSet.add(target);
            }
            // 滑动窗口获取值
            int left = index + 1;
            int right = nums.length - 1;
            while (left < right) {
                if (nums[left] + nums[right] == target) {
                    results.add(Arrays.asList(nums[index], nums[left], nums[right]));
                    // 避免相同的值
                    while (left < right && nums[left] == nums[left + 1]) {
                        left++;
                    }
                    while (left < right && nums[right - 1] == nums[right]) {
                        right--;
                    }
                    // 再次缩短范围, 可能还有满足的值
                    left++;
                    right--;
                } else if (nums[left] + nums[right] < target) {
                    left++;
                } else {
                    right--;
                }
            }
        }
        return results;
    }
}

4.我的提交记录

三数之和

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值