@@ -345,6 +345,76 @@ var threeSum = function(nums) {
345
345
return res
346
346
};
347
347
```
348
+
349
+ 解法二:nSum通用解法。递归
350
+
351
+ ``` js
352
+ /**
353
+ * nsum通用解法,支持2sum,3sum,4sum...等等
354
+ * 时间复杂度分析:
355
+ * 1. n = 2时,时间复杂度O(NlogN),排序所消耗的时间。、
356
+ * 2. n > 2时,时间复杂度为O(N^n-1),即N的n-1次方,至少是2次方,此时可省略排序所消耗的时间。举例:3sum为O(n^2),4sum为O(n^3)
357
+ * @param {number[]} nums
358
+ * @return {number[][]}
359
+ */
360
+ var threeSum = function (nums ) {
361
+ // nsum通用解法核心方法
362
+ function nSumTarget (nums , n , start , target ) {
363
+ // 前提:nums要先排序好
364
+ let res = [];
365
+ if (n === 2 ) {
366
+ res = towSumTarget (nums, start, target);
367
+ } else {
368
+ for (let i = start; i < nums .length ; i++ ) {
369
+ // 递归求(n - 1)sum
370
+ let subRes = nSumTarget (
371
+ nums,
372
+ n - 1 ,
373
+ i + 1 ,
374
+ target - nums[i]
375
+ );
376
+ for (let j = 0 ; j < subRes .length ; j++ ) {
377
+ res .push ([nums[i], ... subRes[j]]);
378
+ }
379
+ // 跳过相同元素
380
+ while (nums[i] === nums[i + 1 ]) i++ ;
381
+ }
382
+ }
383
+ return res;
384
+ }
385
+
386
+ function towSumTarget (nums , start , target ) {
387
+ // 前提:nums要先排序好
388
+ let res = [];
389
+ let len = nums .length ;
390
+ let left = start;
391
+ let right = len - 1 ;
392
+ while (left < right) {
393
+ let sum = nums[left] + nums[right];
394
+ if (sum < target) {
395
+ while (nums[left] === nums[left + 1 ]) left++ ;
396
+ left++ ;
397
+ } else if (sum > target) {
398
+ while (nums[right] === nums[right - 1 ]) right-- ;
399
+ right-- ;
400
+ } else {
401
+ // 相等
402
+ res .push ([nums[left], nums[right]]);
403
+ // 跳过相同元素
404
+ while (nums[left] === nums[left + 1 ]) left++ ;
405
+ while (nums[right] === nums[right - 1 ]) right-- ;
406
+ left++ ;
407
+ right-- ;
408
+ }
409
+ }
410
+ return res;
411
+ }
412
+ nums .sort ((a , b ) => a - b);
413
+ // n = 3,此时求3sum之和
414
+ return nSumTarget (nums, 3 , 0 , 0 );
415
+ };
416
+ ```
417
+
348
418
TypeScript:
349
419
350
420
``` typescript
0 commit comments