일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 간단한 날씨 웹 만들기
- 리트코드
- [파이썬 실습] 심화 문제
- 엘리스
- [파이썬 실습] 기초 문제
- 자바스크립트 split()
- 코드스테이츠
- 엘리스 AI 트랙 5기
- 개발공부
- 코딩부트캠프
- RN 프로젝트
- JavaScript
- 자바스크립트 sort()
- reactnativecli
- 프로그래머스
- 자바스크립트 날씨
- 자바스크립트 reduce()
- 부트캠프
- 프론트개발공부
- 삼항연산자
- HTML
- 개발일기
- 엘리스 ai 트랙
- 자바스크립트 날씨 웹 만들기
- leetcode
- 자바스크립트
- 날씨 웹 만들기
- [파이썬 실습] 중급 문제
- 프론트개발
- [AI 5기] 연습 문제집
- Today
- Total
개발조각
[리트코드] 15. 3Sum 본문
안녕하세요. 개발조각입니다.😊
이제 문제가 슬슬 어려워지네요ㅠ
이번 문제는 너무 답답한 나머지 검색해서 찾은 방법을 적용해보았어요.
알고리즘은 모르면 암기하라 했으니 암기하는 걸로...ㅎㅎ
https://leetcode.com/problems/3sum/
3Sum - LeetCode
Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.
leetcode.com
처음에 단순하게 중첩 for문을 썼는데 런타임 에러가 나더라고요.😂
그래서 도저히 방법을 모르겠어서 찾아봤습니다.
[Leetcode / Javascript] 15. 3Sum
문제는 다음과 같습니다. 숫자의 배열이 주어지고 배열의 원소 중 3개를 더해서 0이 만들어지는 조합을 찾는 문제입니다. 문제 해결방법은 다음과 같습니다. nums 배열을 정렬한 후 제일 앞 원소
wookgu.tistory.com
찾아보니까 대부분 이방식으로 풀더라고요.
그래서 저도 이 방법으로 풀어보았습니다.
해결방안
var threeSum = function(nums) {
nums.sort((a,b)=> a-b);
const answer = [];
for(let i=0; i<nums.length-2; i++){
if(nums[i] === nums[i-1]) continue;
let [point, start, end] = [i, i+1, nums.length-1];
while(start<end){
let sum = nums[point] + nums[start] + nums[end];
if(sum < 0){
while(start<end && nums[start] === nums[start+1]) start++;
start++;
}
else if(sum > 0){
while(start<end && nums[end] === nums[end-1]) end--;
end--;
}
else{
answer.push([nums[point], nums[start], nums[end]]);
while(start<end && nums[start] === nums[start+1]) start++;
while(start<end && nums[end] === nums[end-1]) end--;
start++;
end--;
}
}
}
return answer;
};
이문제를 풀어보니까
이문제는 코드보다는 문제를 어떻게 접근해야 되는지를 파악하면 됩니다.
그럼 접근 방법에 대해 설명하겠습니다.
아래에 있는 예제를 통해 설명하겠습니다.
Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]
nums = [-4, -1, -1, 0, 1, 2]
먼저 정렬을 합니다.
이 문제에서 가장 중요한 건 정렬을 먼저 하고 시작을 해야 됩니다.
이 문제는 아래 규칙 설명을 이해하시면 쉽게 풀실 것 같아서
코드 설명은 따로 안 하고 왜 이렇게 풀었는지 규칙에 대해서만 설명하겠습니다.
규칙 설명
이제 어떻게 풀지에 대한 규칙을 설명을 하자면
이 문제를 풀 때 point, start, end를 설정해줍니다.
nums[i] + nums[j] + nums[k] == 0 있으면
- point : i
- start : j
- end : k
를 가리킵니다.
초기 설정을 아래와 같이 해줍니다.
- point : i
- start : i+1
- end : nums.length-1
3개의 수를 더한 값을 sum이라 하면
sum = nums[point] + nums[start] + nums[end];
- sum < 0 → start++
- sum > 0 → end--
- sum === 0 → start++, end--
위에 조건에 따라 start, end가 이동하게 됩니다.
왜 이렇게 움직이는지 설명을 하기 위해 위에 있던 예제를 토대로 설정해보겠습니다.
sum < 0일 경우
sum이 0보다 작다는 말은 더 큰 수를 더해야 된다는 의미입니다.
그러므로 이미 최댓값인 end를 이동할 필요가 없고 start를 다음으로 큰 수로 이동해야 됩니다.
sum > 0일 경우
sum이 0보다 크다는 말은 더 작은 수를 더해야 된다는 의미입니다.
그러므로 최솟값인 start를 이동할 필요가 없고 end를 다음으로 작은 수로 이동해야 됩니다.
sum === 0일 경우
조합을 찾을 경우 현재 start, end에 위치한 값이 필요 없게 됩니다.
그래서 start++, end--해줍니다.
종합해서 정리하자면
point = 0일 경우
point = 1일 경우
point = 2일 경우
point = 2이면 num[2] = -1입니다.
이전 point = 1이 있을 때 이미 -1(num[1] = -1)이었습니다.
이미 num[point] =-1일 경우일 때의 조합은 다 찾았으므로 또 찾을 필요가 없습니다.
그래서 이럴 경우에는 continue를 써주어 다음으로 넘겼습니다.
point = 3일 경우
이렇게 마무리가 됩니다.
그럼 Input: nums = [-1,0,1,2,-1,-4]일 경우에 [[-1,-1,2],[-1,0,1]] 이렇게 두 가지 조합을 찾게 되는 겁니다.
그러나 여기서 보시면 비효율적인 부분이 있을 겁니다.
이 부분입니다.
이 부분을 보시면 같은 수가 반복하는 걸 보실 수 있습니다.
이전에 num[start] = -1일 경우 조합이 안된다는 걸 아는데 또한 필요가 없잖아요?
그래서 이럴 경우도 다 해결해 주어야 됩니다.
위에 설명이 이해 안되신다면 아래와 같은 경우에 대해 생각하시면 될 것 같습니다.
위의 규칙 설명에 따라 코드를 짰고
아마 이 규칙이 이해되시면 코드 파악하시는데 어렵지 않을 것 같습니다.
'알고리즘🅰 > 리트코드' 카테고리의 다른 글
[리트코드] 17. Letter Combinations of a Phone Number (0) | 2022.09.20 |
---|---|
[리트코드] 16. 3Sum Closest (0) | 2022.09.19 |
[리트코드] 14. Longest Common Prefix (0) | 2022.09.15 |
[리트코드] 13. Roman to Integer (0) | 2022.09.13 |
[리트코드] 12. Integer to Roman (0) | 2022.09.13 |