|
| 1 | +//1.dfs로 풀기 : 시간초과 남 |
| 2 | + |
| 3 | + |
| 4 | +/** |
| 5 | + * @param {number[]} nums |
| 6 | + * @return {number[][]} |
| 7 | + */ |
| 8 | +var threeSum = function(nums) { |
| 9 | + /* |
| 10 | + arr: 현재 고정 배열을 뜻함. dfs가 돌때마다 변경됨. |
| 11 | + start: 끝난 index. arr와 마찬가지로 이것은 for문안에서 변경될 예정. |
| 12 | + dep: dep은 현재 dfs의 dep+1을 해주면 됨. |
| 13 | + */ |
| 14 | + const numsLength = nums.length |
| 15 | + if(numsLength ==3 && nums.reduce((a,b)=>a+b,0) == 0) return [nums] |
| 16 | + |
| 17 | + const ret = [] |
| 18 | + const seen = new Set(); |
| 19 | + nums.sort((a, b) => a - b); |
| 20 | + |
| 21 | + function dfs(arr,start,dep){ |
| 22 | + if(dep == 3) { |
| 23 | + if(arr.length !==3) return |
| 24 | + const arrTotal = arr.reduce((a,b)=>a+b,0); |
| 25 | + if(arrTotal == 0){ |
| 26 | + const string = [...arr].sort((a,b)=>a-b).join(',') |
| 27 | + if(!seen.has(string)){ |
| 28 | + seen.add(string) |
| 29 | + ret.push(arr) |
| 30 | + } |
| 31 | + } |
| 32 | + return |
| 33 | + } |
| 34 | + //만약 start가 0이 되면, i를 감소시켜야하고, 새로운 배열을 추가해야한다. 기존의 배열에 넣어주는게 아니다. |
| 35 | + |
| 36 | + //끝점을 증가시키면서 진행해야함. 현재 고정 arr에 끝점 그 앞의 idx부터 진행해서 0까지 감소시키면서 dfs를 돌리면 된다. |
| 37 | + //idx가 i-1부터이므로, i는 최소 1이어야 가능하다. |
| 38 | + for(let idx = start; idx<numsLength; idx++){ |
| 39 | + // currArr.push([...arr,nums[idx]]) |
| 40 | + //현재 i에 대한 현재 currArr를 만들어준다. |
| 41 | + //만들어준 각 Arr에 대해서, 다시 dfs로 들어가서, 각 배열의 내부의 합이 0인지 확인하고, |
| 42 | + //현재 배열에 대한 set에 대해서 중복이 되는 것은 없는지 확인하면서 넣어준다. |
| 43 | + dfs([...arr,nums[idx]],idx+1,dep+1) |
| 44 | + }} |
| 45 | + dfs([],0,0) |
| 46 | + //마지막에 set으로 triples의 중복을 제거해줘야한다. |
| 47 | + |
| 48 | + return ret |
| 49 | +}; |
| 50 | + |
| 51 | +/* |
| 52 | +시간복잡도: |
| 53 | +nums.sort((a, b) => a - b): 배열 정렬에 O(NlogN) |
| 54 | +
|
| 55 | +N개 숫자 중 3개 선택하는 조합 수 N(N−1)(N−2)/6 |
| 56 | +정확히 알 수는 없지만, |
| 57 | +
|
| 58 | +N^3 이상으로 보임. |
| 59 | +
|
| 60 | +공간복잡도 : O(N^3) => seen 때문. |
| 61 | +
|
| 62 | +*/ |
| 63 | + |
| 64 | +//2. 투포인터로 풀기 |
| 65 | + |
| 66 | +/* |
| 67 | +우선 내가 문제에 대한 이해가 틀렸다. 숫자의 순서가 다르다고 하더라도, 같은 숫자의 조합을 가지고 있다면 안된다. |
| 68 | +값이 원하는 값보다 작으면 오른쪽 값을 옮기고, 크면 왼쪽 값을 옮기는 투포인터 전략을 취해보았다. |
| 69 | +
|
| 70 | + */ |
| 71 | + |
| 72 | +/** |
| 73 | + * @param {number[]} nums |
| 74 | + * @return {number[][]} |
| 75 | + */ |
| 76 | +var threeSum = function(nums) { |
| 77 | + const triplets = [] |
| 78 | + nums.sort((a,b)=>a-b) |
| 79 | + for(let i =0;i<nums.length -2 ;i++){ |
| 80 | + if (i > 0 && nums[i] === nums[i - 1]) continue; |
| 81 | + let low = i+1 |
| 82 | + ,high = nums.length -1 |
| 83 | + |
| 84 | + while(low < high){ |
| 85 | + const three_sum = nums[i] + nums[low] + nums[high] |
| 86 | + if(three_sum<0){ |
| 87 | + low +=1 |
| 88 | + } |
| 89 | + else if(three_sum >0){ |
| 90 | + high -=1 |
| 91 | + } |
| 92 | + else{ |
| 93 | + triplets.push([nums[i],nums[low],nums[high]]) |
| 94 | + while (low < high && nums[low] === nums[low + 1]) low++; |
| 95 | + while (low < high && nums[high] === nums[high - 1]) high--; |
| 96 | + low = low+1 |
| 97 | + high = high -1 |
| 98 | + } |
| 99 | + } |
| 100 | + } |
| 101 | + return triplets |
| 102 | +}; |
0 commit comments