LeetCode算法总结——数组(求和类问题)

二数之和

题目: 给定一个整形数组和一个整数target,返回2个元素的下标,它们满足相加的和为target。你可以假定每个输入,都会恰好有一个满足条件的返回结果。

思路: 一次遍历即可,借助一个Map用于存储value-index,每次去map中get差值,如果为null,则将当前值存入,否则,即找到对应的匹配。注,遍历到两者中的后一个元素时才会找到匹配。

class Solution {
	public int[] twoSum(int[] nums, int target) {
		int[] result = new int[2];
		Map<Integer, Integer> tempMap = new HashMap<>();
		for (int i = 0; i < nums.length; i++) {
			int temp = target - nums[i];
			if (tempMap.containsKey(temp)) {
				result[0] = tempMap.get(temp);
				result[1] = i;
				return result;
			} else {
				tempMap.put(nums[i], i);
			}
		}
		result[0] = 0;
		result[1] = 0;
		return result;
	}
}
三数之和

题目: 给定一个数组S,它包含n个整数,它是否存在3个元素a,b,c,满足a+b+c=0?找出所有满足条件的元素数组。提示:a,b,c三个元素必须是升序排列(也就是满足a ≤ b ≤ c),最终的结果不能包含重复的元素数组。例如给定S为{-1 0 1 2 -1 -4},返回结果是(-1, 0, 1)和(-1, -1, 2)。

思路: 遍历数组建立Map(value-indexList),排序数组,三层循环变为二层,最内层根据差值查询Map即可,以下点可以加快搜索进度

  • 如果第一层循环获得的起始值已经大于0,则直接break。
  • 如果待查找的第三个数的值已经小于第二个数,则直接break。
  • 第一层、第二层从第二次循环开始,如果当前值和前一个值相等,则continue。
	public List<List<Integer>> threeSum(int[] nums) {
		List<List<Integer>> res = new ArrayList<>();
		// nums先进行排序
		Arrays.sort(nums);
		Map<Integer, List<Integer>> map = new HashMap<>();
		for (int i = 0; i < nums.length; i++) {
			int num = nums[i];
			if (map.get(num) == null) {
				List<Integer> subscripts = new ArrayList<>();
				subscripts.add(i);
				map.put(num, subscripts);
			} else {
				map.get(num).add(i);
			}
		}
		for (int i = 0; i <= nums.length - 3; i++) {
			if (nums[i] > 0) {
				break;
			}
			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 finalNum = -nums[i] - nums[j];
				if (finalNum < nums[j]) {
					break;
				}
				List<Integer> subscripts = map.get(finalNum);
				if (subscripts == null) {
					continue;
				}
				for (Integer subscript : subscripts) {
					if (subscript != j && subscript != i) {
						List<Integer> list = new ArrayList<>();
						list.add(nums[i]);
						list.add(nums[j]);
						list.add(nums[subscript]);
						res.add(list);
						break;
					}
				}
			}
		}
		return res;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值