题意:

image.png

解题思路:

  1. 思路:
  2. 1. 首先对 nums 进行从小到大排序;
  3. 2. 枚举第一个数字,然后采用两头夹逼的方式,无重复的寻找剩下的两个数字;
  4. 2.1 初始化left = $i + 1, right = count($num) - 1;
  5. 2.2 left < right 时,如果nums[left] + nums[right] = target, 则增加一组答案,同时left, right 左右移动,否则根据 nums[left] + nums[right] target的大小关系,进行左右移动;
  1. 时间复杂度
  2. 1. 排序的时间复杂度为O(nlogn);
  3. 2. 第一层for情况执行n次,每次内部会遍历 i + 1后面的数字一次,最后情况O(n2)

PHP代码实现:

  1. class Solution {
  2. function threeSum($nums) {
  3. if (!$nums) return [];
  4. sort($nums);
  5. $ret = [];
  6. for ($i = 0; $i < count($nums) - 2; $i++) {
  7. if ($i > 0 && $nums[$i] == $nums[$i - 1]) continue;
  8. $left = $i + 1;
  9. $right = count($nums) - 1;
  10. $needNum = 0 - $nums[$i];
  11. while ($left < $right) {
  12. if ($nums[$left] + $nums[$right] == $needNum) {
  13. array_push($ret, [$nums[$i], $nums[$left], $nums[$right]]);
  14. while ($left < $right && $nums[$left] == $nums[$left + 1]) $left ++;
  15. while ($left < $right && $nums[$right] == $nums[$right - 1]) $right --;
  16. $left ++; $right --;
  17. } else if ($nums[$left] + $nums[$right] > $needNum) {
  18. $right--;
  19. } else $left ++;
  20. }
  21. }
  22. return $ret;
  23. }
  24. }

GO代码实现:

  1. func threeSum(nums []int) [][]int {
  2. var res [][]int
  3. sort.Ints(nums)
  4. fmt.Printf("%v\n", nums)
  5. for i := 0; i < len(nums); i++ {
  6. var left = i + 1
  7. var right = len(nums) - 1
  8. if i > 0 && nums[i] == nums[i - 1] {
  9. continue
  10. }
  11. for left < right {
  12. var sum = nums[i] + nums[left] + nums[right]
  13. if sum == 0 {
  14. res = append(res, []int{nums[i], nums[left], nums[right]})
  15. for left < right && nums[left] == nums[left + 1] {
  16. left++
  17. }
  18. for left < right && nums[right] == nums[right - 1] {
  19. right--
  20. }
  21. left++
  22. right--
  23. } else if sum > 0 {
  24. right--
  25. } else {
  26. left++
  27. }
  28. }
  29. }
  30. return res
  31. }