leetcode题目

自己的原先暴力解法

自己的题解(全部超时):

  1. /**
  2. * @param {number[]} nums
  3. * @return {number[][]}
  4. */
  5. var threeSum = function(nums) {
  6. const sumArr = [];
  7. if(nums.length<3){
  8. return []
  9. }
  10. // 暴力 超时
  11. // let len = nums.length;
  12. // for(let i = 0 ; i < len ; i++ ){
  13. // for(let j = i +1 ; j < len ; j++ ){
  14. // for(let z = j + 1 ; z < len ; z++ ){
  15. // if(nums[i] + nums[j] + nums[z] === 0 && [nums[i] , nums[j] , nums[z]].sort()){
  16. // let sum = [nums[i] , nums[j] , nums[z]].sort()
  17. // if(sumArr.every(c=>`${c}`!==`${sum}`))
  18. // sumArr.push(sum)
  19. // }
  20. // }
  21. // }
  22. // }
  23. // 暴力,不让过
  24. // const _nums = nums.sort((a,b)=>a-b);//排序
  25. // const len = _nums.length
  26. // console.log(_nums,len);
  27. // let maxIndex = len - 1;
  28. // for(let i = 0 ; i < len-2 ; i++ ){
  29. // if(_nums[i]>0){
  30. // break
  31. // }
  32. // if(_nums[i]+_nums[maxIndex -1] +_nums[maxIndex ]<0){
  33. // continue
  34. // }
  35. // for(let j = i + 1; j < len-1 ; j++ ){
  36. // if(_nums[i]+_nums[j] > 0 ){
  37. // break
  38. // }
  39. // if(_nums[i]+_nums[j] +_nums[maxIndex ]<0){
  40. // continue
  41. // }
  42. // for(let z = j +1 ; z < len ; z++ ){
  43. // if(_nums[i] + _nums[j] + _nums[z] > 0 ){
  44. // break
  45. // }
  46. // if(_nums[i] + _nums[j] + _nums[z] === 0 ){
  47. // let sum = [_nums[i] , _nums[j] , _nums[z]]
  48. // if(sumArr.every(c=>`${c}`!==`${sum}`))
  49. // sumArr.push(sum)
  50. // }
  51. // }
  52. // }
  53. // }
  54. //
  55. const _nums = nums.sort((a,b)=>a-b);//排序
  56. const len = _nums.length;
  57. const arr1 = {}
  58. for(let i = 1;i < len - 1 ; i++ ){
  59. for(let j = len - 1;j > i ; j-- ){
  60. const sum = _nums[i] +_nums[j]
  61. // console.log(sum,i,j,_nums[i] ,_nums[j])
  62. if(sum<0){
  63. break;
  64. }
  65. let arr = arr1[sum];
  66. const key= `${[_nums[i],_nums[j]]}`
  67. if(arr){
  68. // if(_nums[i]===_nums[arr[len1-1][0]]&&_nums[j]===_nums[arr[len1-1][1]]&&)
  69. arr[key] = [i,j]
  70. }else {
  71. arr1[sum] = {[key]:[i,j]}
  72. }
  73. }
  74. }
  75. console.log(arr1,_nums)
  76. for(let i = 0;i < len - 2 ; i++ ){
  77. const first = arr1[-_nums[i]]
  78. if(first ){
  79. for(let k in first){
  80. const c= first[k]
  81. if(c[0]>i){
  82. const a = [_nums[i]].concat(c.map(cc=>_nums[cc]))
  83. if(sumArr.every(c=>`${c}`!==`${a}`))
  84. sumArr.push(a)
  85. }
  86. }
  87. // arr1[-_nums[i]].forEach(c=>{
  88. // if(c[0]>i){
  89. // const a = [_nums[i]].concat(c.map(cc=>_nums[cc]))
  90. // if(sumArr.every(c=>`${c}`!==`${a}`))
  91. // sumArr.push(a)
  92. // }
  93. // })
  94. }
  95. }
  96. return sumArr
  97. };

双指针

「双指针」,当我们需要枚举数组中的两个元素时,如果我们发现随着第一个元素的递增,第二个元素是递减的,那么就可以使用双指针的方法,将枚举的时间复杂度从 O(N^2)减少至 O(N)O(N)。为什么是 O(N) 呢?这是因为在枚举的过程每一步中,「左指针」会向右移动一个位置,而「右指针」会向左移动若干个位置,这个与数组的元素有关,但我们知道它一共会移动的位置数为 O(N),均摊下来,每次也向左移动一个位置,因此时间复杂度为 O(N)

正确的解法

  1. /**
  2. * @param {number[]} nums
  3. * @return {number[][]}
  4. */
  5. var threeSum = function(nums) {
  6. let sumArr = [];
  7. if(nums.length<3){
  8. return []
  9. }
  10. // 全是0过不了
  11. if(Array.from(new Set(nums)).length===1&&nums[0]===0){
  12. return [[0,0,0]]
  13. }
  14. // 暴力 超时
  15. let len = nums.length;
  16. const _nums = nums.sort((a,b)=>a-b);//排序
  17. for(let i = 0 ; i < len - 2 ; i++ ){
  18. if(_nums[i]>0){
  19. break
  20. }
  21. if(_nums[i]+_nums[len - 2] +_nums[len - 1 ]<0){
  22. continue
  23. }
  24. for(let j = i +1 ; j < len - 1; j++ ){
  25. if(_nums[i]+_nums[j] >0){
  26. break;
  27. }
  28. if(_nums[i]+_nums[j] +_nums[len - 1 ]<0){
  29. continue
  30. }
  31. let preZ = len - 1
  32. for(let z = len - 1 ; z > j ; z-- ){
  33. if(_nums[i] + _nums[j] + _nums[z] === 0 ){
  34. let sum = [_nums[i] , _nums[j] , _nums[z]]
  35. // if(sumArr.every(c=>`${c}`!==`${sum}`))
  36. sumArr.push(JSON.stringify(sum));
  37. preZ = z - 1;
  38. // while(_nums[preZ]===_nums[z]){
  39. // preZ--
  40. // }
  41. break
  42. }
  43. }
  44. }
  45. }
  46. sumArr = Array.from(new Set(sumArr)).map(c=>JSON.parse(c))
  47. return sumArr
  48. };