16--最接近的三数之和
GET{
方法: 双指针法
* 先让数组有序(好像牵扯到数组的问题, 排序都很有必要)
* 然后每次固定一个元素, 再去寻找另外两个元素, 也就是双指针
代码实现:
(1) 利用 Arrays.sort(nums) 对数组进行排序。
(2) 初始化一个用于保存结果的值 result = nusm[0] + nums[1] + nums[2] (不要自己设初值,直接从数组中抽取三个元素,假设这是最接近的三数之和,然后再更新就是了)。
(3) 利用下标 i 对数组进行遍历,此时就是在固定第一个元素,注意,下标 i 的边界为 i < nums.length-2,否则设置指针的时候会出现数组越界。
(4) 每次遍历的过程中设置两个指针,分别是 left = i + 1、right = nums.length - 1。
(5) 检查 sum = nums[i] + nums[left] + nums[right]与 target 的距离,如果该距离比之前保存的 result 与 target 的距离更小,就更新 result。
(6) 然后就是移动双指针。
(7) 如果 sum 的值比 target 大,那么我们让 right--,因为数组是有序的,right --会使得下一次的 sum 更小,也就更接近 target 的值
(8) 同理,如果 sum 的值 target 小,那么我们让 left++。·
(9) left++ 和 right-- 的界限自然是 left != right,如果 left == right,说明我们已经将所有的元素都遍历过一遍了。
(10) 重复上面的操作,直到i循环结束为止,返回 result。
运用拓展:
1 此种算法适用于需要多层循环遍历找到其中某一个固定组合的情景
2 对于元素重复问题, 提供了解决办法, 拓展运用性较强, 关键代码如下
1 if(sum > target){ 2 right--; 3 // 解决nums[right]重复 4 while(left != right && nums[right] == nums[right+1]) 5 right--; 6 } 7 else{ 8 left++; 9 // 解决nums[left]重复 10 while(left != right && nums[left] == nums[left-1]) 11 left++; 12 }
3 对于偷懒时机的敏感, 此次找出了超越界限时的两个极端顶点情况, 以及差值等于0直接返回的情况 此种感觉需要锻炼出来
}