LeetCode016——最接近的三数之和

版权声明:版权所有,转载请注明原网址链接。 https://blog.csdn.net/qq_41231926/article/details/82177199

原题链接:https://leetcode-cn.com/problems/3sum-closest/description/

题目描述:

知识点:数组、对撞双指针

思路一:暴力解法

三重循环遍历nums数组。时间复杂度是O(n ^ 3),其中n为数组nums的长度。空间复杂度是O(1)。

JAVA代码:

public class Solution {

	public int threeSumClosest(int[] nums, int target) {
		int n = nums.length;
		int diff = Integer.MAX_VALUE;
		int result = 0;
		for(int i = 0; i < n; i++) {
			for(int j = i + 1; j < n; j++) {
				for(int k = j + 1; k < n; k++) {
					if(Math.abs(nums[i] + nums[j] + nums[k] - target) < diff) {
						diff = Math.abs(nums[i] + nums[j] + nums[k] - target);
						result = nums[i] + nums[j] + nums[k];
					}
				}
			}
		}
		return result;
	}
}

LeetCode解题报告:

思路二:第一个指针从前往后遍历,另外两个指针在第一个指针设定的范围内对撞查找

本题和LeetCode15——三数之和很像,其实本题比LeetCode15要简单,因为本题只需要求出与target最接近的三个数的和,而不用去管这三个数的组合是否重复。参照LeetCode15的解题思路,我们依然可以使用对撞双指针来解决我们的问题。关于LeetCode15——三数之和的JAVA题解,可以参见我的另一篇博文:https://blog.csdn.net/qq_41231926/article/details/81449878

首先,得对数组nums进行排序。设立一个指针i从前往后一直遍历排序后的nums数组,直到倒数第三个元素。因为如果到了倒数第二个元素,那么后面就只剩下一个元素,取不满三个元素了。接着就是我们的滑动窗口法遍历排序后数组中索引为i + 1到n - 1范围内的元素,其中n为数组nums的长度,根据题意来实现我们的算法。注意,对撞双指针left和right的变动应当发生在对当前三个元素之和的结果处理之后

排序的时间复杂度是O(nlogn)。在遍历过程中内部循环由于使用了对撞双指针做优化,因此时间复杂度是O(n ^ 2)级别的。总的时间复杂度是O(n ^ 2)级别的。这个思路中没有使用额外的空间,空间复杂度是O(1)级别的。

JAVA代码:

public class Solution {

	public int threeSumClosest(int[] nums, int target) {
		int n = nums.length;
		int diff = Integer.MAX_VALUE;
		int result = 0;
		Arrays.sort(nums);
		for(int i = 0; i < n - 2; i++) {
			int left = i + 1;
			int right = n - 1;
			while(left < right) {
				if(nums[i] + nums[left] + nums[right] < target) {
					if(Math.abs(nums[i] + nums[left] + nums[right] - target) < diff) {
						diff = Math.abs(nums[i] + nums[left] + nums[right] - target);
						result = nums[i] + nums[left] + nums[right];
					}
					left++;
				}else if(nums[i] + nums[left] + nums[right] == target) {
					return target;
				}else {
					if(Math.abs(nums[i] + nums[left] + nums[right] - target) < diff) {
						diff = Math.abs(nums[i] + nums[left] + nums[right] - target);
						result = nums[i] + nums[left] + nums[right];
					}
					right--;
				}
			}
		}
		return result;
	}
}

LeetCode解题报告:

猜你喜欢

转载自blog.csdn.net/qq_41231926/article/details/82177199
今日推荐