가장 빠르게 생각난 방법은 이중 포문을 써서 모든 경우의 수를 조사하는 것이였다.
대신 이 방법은 시간복잡도가 O(N^2) 이였다.
코드
class Solution {
public int[] twoSum(int[] nums, int target) {
for(int i=0; i<nums.length; i++){
for(int j=i+1; j<nums.length; j++){
if(nums[i] + nums[j] == target)return new int[] {i, j};
}
}
return new int[2];
}
}
결과 : 성공
Runtime
Memory
역시나 시간이 너무 오래걸리는 방법이였다. 시간을 줄이기 위해 다른 방법을 고민해보았다.
sort하고, 투포인터를 활용해서 이분탐색을 해야하나 고민했는데, 반례들이 자꾸 떠올라서 안 될 것 같았다.
결국, 다른 분의 코드를 참고했는데, 이것은 map을 사용한 방법이였다.
map
의 key
값을 nums
로, value
를 nums의 갯수
로 저장하였다.
그리고 nums를 탐색하며 map에 taget-nums
가 없다면 해당 nums를 추가
하고, map에 있다면 이 두개가 정답인 한 쌍
이라는 것이기에 반환하면 됐다.
코드는 아래와 같다.
코드
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> numMap = new HashMap<>();
int n = nums.length;
for (int i = 0; i < n; i++) {
int complement = target - nums[i];
if (numMap.containsKey(complement)) {
return new int[]{numMap.get(complement), i};
}
numMap.put(nums[i], i);
}
return new int[]{};
}
}
결과 : 성공
보면 Runtime에서 확실히 차이가 많이났다.
시간 개선 된 코드는 map을 사용했기에 O(1)로 값을 찾을 수 있고 이것을 n 번 반복이기에 O(N)이였다.
HashMap을 사용하면 확실히 시간을 많이 줄일 수 있는 것 같다.
이러 방법으로 풀 수 있는 문제를 여러번 풀어봐야겠다.