15. 三数之和(筛选数据)

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

  1/**
2 * @param {number[]} nums
3 * @return {number[][]}
4 */

5
6var threeSum = function (nums) {
7    // 去重到每个最多只剩两个(如果是0, 至多3个)
8    nums = unique(nums)
9    if (nums.length < 3return [];
10
11    var r = [];
12    nums.sort((a, b) => a - b);
13
14    for (var i = 0; i < nums.length - 2; i++) {
15        var newNums = nums.slice(i + 1);
16
17        //  a + b + c = 0 => a + b = -c 将三数之和转 化为 两数之和
18        var a = twoSum(newNums, nums[i]);
19        if (a.length !== 0) r = r.concat(a)
20    }
21
22    return depute(r)
23}
24
25// 筛选数据至每个数据出现不超过两次(0三次)
26/**
27 * @param {number[]} nums
28 * @return {number[]} 
29 */

30var unique = function(nums) {
31    // 出现次数不超过2次(如果是0那就3次)
32    var r = [], r1 = []
33    for(var i=0; i<nums.length; i++) {
34        if(r.indexOf(nums[i]) === -1){
35            r.push(nums[i])
36            nums.splice(i, 1)
37            i--
38        }
39    }
40
41    for(var i=0; i<nums.length; i++) {
42        if(r1.indexOf(nums[i]) === -1){
43            r1.push(nums[i])
44            nums.splice(i, 1)
45            i--
46        }
47    }
48
49    var r = r.concat(r1)
50
51    // 如果还有 0
52    for(var i=0; i<nums.length; i++) {
53        if(nums.indexOf(0) !== -1) {
54            r.push(0)
55            break
56        }
57    }
58
59    return r
60}
61
62// 两数之和
63/**
64 * @param {number[]} numbers
65 * @param {number} target
66 * @return {number[]} 
67 */

68var twoSum = function (numbers, target) {
69    var r = [], l = numbers.length
70
71    for (var i = 0; i < l - 1;) { // i < l-1 而不是 i < l
72        if (numbers[i] + numbers[l - 1] < -target) {
73            i++
74            continue
75        }
76        if (numbers[i] + numbers[l - 1] > -target) {
77            l--
78            continue
79        }
80        if (numbers[i] + numbers[l - 1] === -target) {
81            var a = [target, numbers[i], numbers[l - 1]]
82            r.push(a)
83            i++
84            l--
85        }
86    }
87
88    return r
89}
90
91// 深度去重
92/**
93 * @param {number[]} a
94 * @return {number[]} 
95 */

96var depute = function (a) {
97    for (var i = 0; i < a.length; i++) {
98        a[i] = JSON.stringify(a[i])
99    }
100
101    var newArr = new Set(a)
102    newArr = Array.from(newArr)
103
104    for (var j = 0; j < newArr.length; j++) {
105        newArr[j] = JSON.parse(newArr[j])
106    }
107
108    return newArr
109}
posted @ 2018-10-20 17:01  rencoo  阅读(258)  评论(0编辑  收藏  举报