Description
Given an integer array nums of length n and an integer target, find three integers
in nums such that the sum is closest to target.
Return the sum of the three integers.
You may assume that each input would have exactly one solution.
Solution
Solve this problem by using three pointers.
Sort input nums.
Define res and initialize it's values to any 3 combination of nums. It'll hold
our sought value.
Iterate the nums var. This loop's index, i, is the first pointer.
Within that loop, we initialize the next two pointers, left and right.
Loop while l is smaller than r.
Sum the values of nums[i] + nums[l] + nums[r] and compare it to target.
If the sum larger than target, decrement r. Otherwise increment l.
Check if the diff absolute value of cur minus target is less than diff of
absolute value of res minus target.
If so, reassign res to cur.
Define response var, sort nums, iterate, return res
Initialize var which holds sought value, res, which we update while iterating
through input nums.
Iterate the nums input. This loops incrementor i will be the first pointer.
Return res.
1// JS syntax is more flexible than statically typed languages2// Input parameters don't require type annotation3 4var threeSumClosest = function(nums, target) {5 var res = nums[0] + nums[1] + nums[2];6 nums = nums.sort((a, b) => a - b);7 8 for (var i = 0; i < nums.length - 2; i ++) {9 }10 return res11};1// "nums: number[]" means input param is 'nums' is a list of numbers2 3function threeSumClosest(nums: number[], target: number): number {4 var res = nums[0] + nums[1] + nums[2];5 nums = nums.sort((a, b) => a - b);6 7 for (var i = 0; i < nums.length - 2; i ++) {8 }9 return res10};1// Dart requires typing return value, the 'int' before threeSumClosest.2// It's parameters are also typed. The 'int' before target3 4class Solution {5 int threeSumClosest(List<int> nums, int target) {6 var res = nums[0] + nums[1] + nums[2];7 nums.sort();8 9 for (var i = 0; i < nums.length - 2; i ++) {10 }11 return res;12 }13}1// Java requires typing of input parameters and variables2// Unlike TS the type comes before the param in function signature.3 4class Solution {5 public int threeSumClosest(int[] nums, int target) {6 int res = nums[0] + nums[1] + nums[2];7 Arrays.sort(nums);8 9 for (int i = 0; i < nums.length - 2; i++) {10 }11 12 return res;13 }14}1# In Python3 typing for the function's signature and return value are optional2 3class Solution:4 def threeSumClosest(self, nums: List[int], target: int) -> int:5 nums.sort()6 res = nums[0] + nums[len(nums) - 1] + nums[len(nums) - 2]7 8 for i, n in enumerate(nums):9 10 return res1// := allows Go to infer type of 'res'2// from the type of the expression on the right.3 4// Go also has type annotation on the right of the signature(like TS)5 6func threeSumClosest(nums []int, target int) int {7 res := nums[0] + nums[1] + nums[2]8 sort.Ints(nums[:])9 10 for i := 0; i < len(nums) - 2; i++ {11 }12 13 return res14}Use i pointer to initialize next pointer and nest loop
Set l pointer to i + 1 and r to the length of nums - 1
In this way we can work our farthest left pointer from left to right
and then have the next 2 pointers behave as a sliding window.
Loop while left is smaller than right.
In the loop, sum the values of nums[i] + nums[l] + nums[r].
Check this sum, if it matches target return cur as we can't get any closer
to target.
Otherwise compare is it's greater than target of less and increment/decrement l and r as appropriate.
Remember, the idea here is we want the sum to be 0.
1var threeSumClosest = function(nums, target) {2 var res = nums[0] + nums[1] + nums[2];3 nums = nums.sort((a, b) => a - b);4 5 for (var i = 0; i < nums.length - 2; i ++) {6 var l = i + 17 var r = nums.length - 18 9 while (l < r) {10 var cur = nums[i] + nums[l] + nums[r]11 if (cur == target) return cur12 if (cur > target) {13 r -= 114 } else if (cur < target) {15 l += 116 }17 }18 }19 return res20};1function threeSumClosest(nums: number[], target: number): number {2 var res = nums[0] + nums[1] + nums[2];3 nums = nums.sort((a, b) => a - b);4 5 for (var i = 0; i < nums.length - 2; i ++) {6 var l = i + 17 var r = nums.length - 18 9 while (l < r) {10 var cur = nums[i] + nums[l] + nums[r]11 if (cur == target) return cur12 if (cur > target) {13 r -= 114 } else if (cur < target) {15 l += 116 }17 }18 }19 return res20};1class Solution {2 int threeSumClosest(List<int> nums, int target) {3 var res = nums[0] + nums[1] + nums[2];4 nums.sort();5 6 for(var i = 0; i < nums.length - 2; i ++) {7 var l = i + 1;8 var r = nums.length - 1;9 10 while (l < r) {11 var cur = nums[i] + nums[l] + nums[r];12 if (cur == target) return cur;13 if (cur > target) {14 r -= 1;15 } else if (cur < target) {16 l += 1;17 }18 }19 }20 return res;21 }22}1class Solution {2 public int threeSumClosest(int[] nums, int target) {3 int res = nums[0] + nums[1] + nums[2];4 Arrays.sort(nums);5 6 for (int i = 0; i < nums.length - 2; i++) {7 int l = i + 1;8 int r = nums.length - 1;9 10 while (l < r) {11 int cur = nums[i] + nums[l] + nums[r];12 13 if (cur > target) {14 r -= 1;15 } else {16 l += 1;17 }18 }19 }20 21 return res;22 }23}1#2 3class Solution:4 def threeSumClosest(self, nums: List[int], target: int) -> int:5 nums.sort()6 res = nums[0] + nums[len(nums) - 1] + nums[len(nums) - 2]7 8 for i, n in enumerate(nums):9 l = i + 110 r = len(nums) - 111 12 while l < r:13 curSum = nums[i] + nums[l] + nums[r]14 15 if curSum == target:16 return curSum17 if curSum > target:18 r -= 119 else:20 l += 121 22 return res1//2 3func threeSumClosest(nums []int, target int) int {4 res := nums[0] + nums[1] + nums[2]5 sort.Ints(nums[:])6 7 for i := 0; i < len(nums) - 2; i++ {8 l := i + 19 r := len(nums) - 110 11 for l < r {12 cur := nums[i] + nums[l] + nums[r]13 if cur > target {14 r -= 115 } else {16 l += 117 }18 }19 }20 21 return res22}Check the difference between cur and res
Compare the absolute different of cur - target
and res - target to find which is closet to zero.
If cur is smaller then reassign res to cur.
Use math's absolute in case the value becomes negative.
And finally optimize the outer loop comparing if the previous i is the same as this i.
If so, continue to the next iteration.
1// Math.abs is helpful here.2 3var threeSumClosest = function(nums, target) {4 var res = nums[0] + nums[1] + nums[2];5 nums = nums.sort((a, b) => a - b);6 7 for (var i = 0; i < nums.length - 2; i ++) {8 if (i > 0 && nums[i] == nums[i - 1]) {9 continue10 }11 var l = i + 112 var r = nums.length - 113 14 while (l < r) {15 var cur = nums[i] + nums[l] + nums[r]16 if (cur == target) return cur17 if (cur > target) {18 r -= 119 } else if (cur < target) {20 l += 121 }22 23 if (Math.abs(cur - target) < Math.abs(res - target)) {24 res = cur25 }26 }27 }28 return res29};1//2 3function threeSumClosest(nums: number[], target: number): number {4 var res = nums[0] + nums[1] + nums[2];5 nums = nums.sort((a, b) => a - b);6 7 for (var i = 0; i < nums.length - 2; i ++) {8 if (i > 0 && nums[i] == nums[i - 1]) {9 continue10 }11 var l = i + 112 var r = nums.length - 113 14 while (l < r) {15 var cur = nums[i] + nums[l] + nums[r]16 if (cur == target) return cur17 if (cur > target) {18 r -= 119 } else if (cur < target) {20 l += 121 }22 23 if (Math.abs(cur - target) < Math.abs(res - target)) {24 res = cur25 }26 }27 }28 return res29};1//2 3class Solution {4 int threeSumClosest(List<int> nums, int target) {5 var res = nums[0] + nums[1] + nums[2];6 nums.sort();7 8 for (var i = 0; i < nums.length - 2; i ++) {9 if (i > 0 && nums[i] == nums[i - 1]) {10 continue;11 }12 var l = i + 1;13 var r = nums.length - 1;14 15 while (l < r) {16 var cur = nums[i] + nums[l] + nums[r];17 if (cur == target) return cur;18 if (cur > target) {19 r -= 1;20 } else if (cur < target) {21 l += 1;22 }23 24 if ((cur - target).abs() < (res - target).abs()) {25 res = cur;26 }27 }28 }29 return res;30 }31}1//2 3class Solution {4 public int threeSumClosest(int[] nums, int target) {5 int res = nums[0] + nums[1] + nums[2];6 Arrays.sort(nums);7 8 for (int i = 0; i < nums.length - 2; i++) {9 if (i > 0 && nums[i] == nums[i - 1]) {10 continue;11 }12 13 int l = i + 1;14 int r = nums.length - 1;15 16 while (l < r) {17 int cur = nums[i] + nums[l] + nums[r];18 19 if (cur > target) {20 r -= 1;21 } else {22 l += 1;23 }24 25 if (Math.abs(cur - target) < Math.abs(res - target)) {26 res = cur;27 }28 }29 }30 31 return res;32 }33}1# Python has abs as well.2 3class Solution:4 def threeSumClosest(self, nums: List[int], target: int) -> int:5 nums.sort()6 res = nums[0] + nums[len(nums) - 1] + nums[len(nums) - 2]7 8 for i, n in enumerate(nums):9 if (i > 0) and nums[i - 1] == nums[i]:10 continue11 l = i + 112 r = len(nums) - 113 14 while l < r:15 curSum = nums[i] + nums[l] + nums[r]16 17 if curSum == target:18 return curSum19 if curSum > target:20 r -= 121 else:22 l += 123 24 if abs(curSum - target) < abs(res - target):25 res = curSum26 27 return res1// Go doesn't have built in support for mathematical abs2// so we have to implement it ourselves.3 4func absInt(x int) int {5 return absDiffInt(x, 0)6}7 8func absDiffInt(x, y int) int {9 if x < y {10 return y - x11 }12 return x - y13}14 15func threeSumClosest(nums []int, target int) int {16 res := nums[0] + nums[1] + nums[2]17 sort.Ints(nums[:])18 19 for i := 0; i < len(nums) - 2; i++ {20 if i > 0 && nums[i] == nums[i - 1] {21 continue22 }23 24 l := i + 125 r := len(nums) - 126 27 for l < r {28 cur := nums[i] + nums[l] + nums[r]29 if cur > target {30 r -= 131 } else {32 l += 133 }34 35 if absInt(cur - target) < absInt(res - target) {36 res = cur37 }38 }39 }40 41 return res42}