/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
let ans = [];
for(let i = 0; i < nums.length - 1; i += 1){
for(let j = i + 1; j < nums.length; j += 1){
let one = nums[i];
let two = nums[j];
if(one + two === target){
ans = [i, j];
break;
}
}
}
return ans;
};
hash table을 사용하지 않고 문제를 푸는 것에만 집중한 풀이이다.
for문을 이중으로 사용했기 때문에 시간복잡도가 O(n^2)이다.
이번에는 hash table을 사용해보려고 한다.
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = (nums, target) => {
// Map에 넣고
// nums에 있는 값이 key가 되고, 인덱스가 value
// diff를 key로 사용하여 검색한다.
let hashMap = new Map();
// hash table 생성
for(let i = 0; i < nums.length; i++){
// 이미 key로 존재하는 값이 또 들어오는 경우,
// diff(= target - value)가 들어온 값과 일치한다면 그대로 result 생성해서 반환한다.
// 다르다면 이 둘은 정답이 될 수 없으므로(문제 조건이 하나의 해만 존재한다고 하기 때문)
// 값을 교체하든 안하든 상관이 없다.
if(hashMap.has(nums[i])){
if(nums[i] !== target - nums[hashMap.get(nums[i])]){
continue;
}
return [hashMap.get(nums[i]), i];
} else {
hashMap.set(nums[i], i);
}
}
// 위에서 답이 반환되지 않은 경우 두 개의 서로 다른 값이 정답이므로
// hashMap을 순회하면서 정답을 찾아간다.
for (const [key, value] of hashMap.entries()) {
const diff = target - key;
// 자기 자신을 검색하는 일 방지.
if(diff === key){
continue;
}
if(hashMap.has(diff)){
return [value, hashMap.get(diff)];
}
}
};
Map 객체를 사용하여 hash table을 구현했다.
결과적으로는 인덱스를 담은 배열을 반환해야하기 때문에
key가 nums의 원소값, value가 nums의 인덱스가 되도록 만들었다.
hash table 생성 과정에서 같은 key가 생성되려고 한다면,
그 값과 현재 hash table에 존재하는 key의 합이 target이 되는지 확인한다.
만약, target과 일치한다면 이는 정답이 된다.
문제 조건에서 단 하나의 답만이 존재한다고 했기 때문에,
같은 두 값의 합이 target이 아니라면 두 값은 쓸모가 없어진다.
같은 값이 두 개 있게되면, 단 하나의 정답은 존재할 수 없기 때문이다.
이미 존재하던 key와 다른 값을 가지는 key가 정답이 될 수도 있고,
이번에 들어온 중복된 값을 가진 key와 다른 값을 가지는 key가 정답이 될 수 있기 때문에
문제의 조건인 유일성이 파괴되기 때문이다.
만약, 이런 경우의 수가 없이 전부 hash table에 들어가게 되면,
hash table을 순회하며 답을 찾아내도록 한다.
여기서도 마찬가지로 target과 key의 차를 이용하여 또 다른 key를 탐색한다.
만약, target이 9이고 현재 순회 중인 key가 3이라면,
6을 key로 갖는 값을 찾으면 된다.
const twoSum = (nums, target) => {
const map = {};
for (let i = 0; i < nums.length; i++) {
const another = target - nums[i];
if (another in map) {
return [map[another], i];
}
map[nums[i]] = i;
}
return null;
};
필자와 같은 논리를 사용하셨는데, 이 분은 일반 객체를 사용하셨다.
Map 객체로 인한 메서드 사용이 사라져서 훨씬 간단해 보인다.
target과 현재 숫자를 뺀 값을 another로 설정한다.
만약 map 객체에 another이라는 key가 없으면,
현재 숫자를 key로 가지고 인덱스를 value로 가지는 속성값을 생성한다.
만약 map 객체에 another이라는 key가 있으면,
another를 key로 가지는 value와 현재의 인덱스를 배열 형태로 반환한다.
작은 인덱스부터 시작해서 map 객체에 key-value로 넣어놨기 때문에,
반복문 내에서 접근하기가 쉽다.