[LeetCode] easy : Two Sum

풀이

여러 시간복잡도로 풀어볼 수 있는 좋은 문제라고 생각한다. 일단 문제보자마자 2중반복으로 전체탐색을 해보면 512ms정답을 얻을 수 있었다. O(n^2) 그리고 sorting을 한 후 이분탐색으로 접근을 하면 조금 더 좋은 답을 얻을 수 있다. O(nlogn)

숫자의 범위가 안나와있어서 메모이제이션으로 O(n)으로 풀어보려고 헀는데 런타임에러가 역시 나더라. 그래서 map을 사용해서 16ms를 얻을 수 있었다. O(n) 정렬을 수행안하는 unordered_map은 해싱기반이라 O(n)이다.

이풀이가 상위15%이므로 더좋은 풀이도 존재한다. unordered_map 1개로 입력과 서치를 동시에 수행하는 것이 더좋은 풀이이다. 아래에 0초 코드를 같이 적어두었다.

내풀이는 그냥 메모이제이션 처럼 unordered_map 2개를 nums[i]:빈도 , nums[i]:마지막idx 로 키밸류쌍을 잡아주고 값을 넣어준 다음에 같은수 2개가 정답이 되는 예외처리만 해주고 map.count로 정답을 접근해 값을 바로 찾아보는 방식이다.

코드

LeetCode - Two Sum


class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {

      ios_base::sync_with_stdio(false);
	    cin.tie(NULL);
	    cout.tie(NULL);

        //nums[i] , key숫자나온횟수
        unordered_map<int,int> m;
        //nums[i], 해당숫자 마지막 idx
        unordered_map<int, int > m_idx;
        
        vector<int> sol;
        
        //map에 nums넣기
        for(int i=0;i<nums.size();i++){
            if (m.count(nums[i]) == 0) {
			    m[nums[i]] = 1;
		    }
		    else {
			    m[nums[i]] = m[nums[i]] + 1;
		    }
		    m_idx[nums[i]] = i;
        }   
        
        for(int i=0;i<nums.size();i++){
            int tmp = target - nums[i];
		    //같은수 2개 엘리먼트가 답을 만드는경우
		    if (tmp == nums[i]) {
			    if (m.count(tmp)>0 && m[nums[i]] < 2) {
				    //2개미만이면 답이되지않음.
				    continue;
			    }
		    }

		    //정답을 발견한 경우
		    if (m.count(tmp) > 0) {
			    sol.push_back(i);
			    sol.push_back(m_idx[tmp]);
                break;
		    }
        }
        
        return sol;
    }
};
0ms 

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        int m = nums.size();
        if(m <= 1)return {};
        unordered_map<int,int> mp;
        for(int i = 0; i < m; ++i){
            if(mp.count(target-nums[i]) != 0){
                return {mp[target-nums[i]],i};
            }else{
                mp[nums[i]] = i;
            }
        }
        return {};
    }
};
Written on August 7, 2020