2. FrontEnd/LeetCode / / 2024. 8. 28. 11:32

[LeetCode] 1. 두 개의 합

728x90

# 문제

정수 배열 nums 과 정수가 주어지면 target, 두 숫자의 인덱스를 반환하여 두 숫자의 합이target . 가 되도록 합니다.
각 입력에 대한 해답은 정확히 하나만 있다고 가정할 수 있으며 , 같은 요소를 두 번 사용할 수 없습니다 . 어떤 순서로든 답변을 제출할 수 있습니다.

예시 1:

입력: nums = [2,7,11,15], target = 9
 출력: [0,1]
 설명: nums[0] + nums[1] == 9이므로 [0, 1]을 반환합니다.

예시 2:

입력: nums = [3,2,4], target = 6
 출력: [1,2]

예시 3:

입력: nums = [3,3], target = 6
 출력: [0,1]

 

제약사항:

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • 유효한 답은 오직 하나뿐입니다.

후속 질문:  시간 복잡도 보다 낮은 알고리즘을 만들어낼 수 있나요 ?O(n2) 

 

# 해설

twoSum함수는 주어진 배열 nums와 목표값 target을 이용하여 배열의 두 숫자의 합이 target과 일치하는 두 숫자의 인덱스를 찾는 문제를 해결하는 함수이다. 

두가지 접근 방법이 있다

1. 브투스포스 (Brute Force) = 이중루프를 사용하여 모든 쌍을 검사한다.

이 방법은 간단하지만 시간복잡도가 O(n2)이다. 배열의 크기가 크면 성능이 좋지 않지만 이해하기는 쉬움 
(개인적으로 이게 읽기 편하다ㅠ)

function twoSum(nums: number[], target: number): number[] {
  // 배열의 길이만큼 반복
  for (let i = 0; i < nums.length; i++) {
    // i번째 숫자와 다른 숫자들을 비교
    for (let j = i + 1; j < nums.length; j++) {
      // 두 숫자의 합이 목표값과 같은지 확인
      if (nums[i] + nums[j] === target) {
        // 목표값을 만드는 두 숫자의 인덱스를 반환
        return [i, j];
      }
    }
  }
  
  // 목표값을 만드는 쌍이 없으면 빈 배열 반환
  return [];
}

1) 이중루프 사용 = 배열을 두번 반복하여 모든 가능한 쌍을 검사한다
(1) 첫번째 루프는 배열의 각 숫자를 선택
(2) 두번째 루프는 선택된 숫자 이후의 모든 숫자를 검사한다
2) 합 비교 = 현재 선택된 두 숫자의 합이 target과 같은지 확인
3) 인덱스 반환 = 합이 target과 같으면 두 숫자의 인덱스를 배열형태로 반환
4) 결과 없음 = 만약 어떤 쌍도 목표값을 만들지 않는다면 빈 배열 반환

2. 해시맵 = 해시맵을 사용하여 이미 본 숫자와의 쌍을 찾는다

해시맵 접근법이 더 효율적이고 시간 복잡도가 O(n)이고 공간 복잡도 또한 O(n)이다

function twoSum(nums: number[], target: number): number[] {
  const numMap = new Map<number, number>(); // 숫자와 그 인덱스를 저장할 해시 맵

  for (let i = 0; i < nums.length; i++) {
    const complement = target - nums[i]; // 목표값에서 현재 숫자를 뺀 값

    if (numMap.has(complement)) {
      // 보완 숫자가 해시 맵에 존재하면, 쌍을 찾은 것이므로 인덱스를 반환
      return [numMap.get(complement)!, i];
    }

    // 현재 숫자와 인덱스를 해시 맵에 추가
    numMap.set(nums[i], i);
  }

  // 유효한 쌍을 찾지 못한 경우, 빈 배열을 반환 (문제 설명에 따라 필요 시)
  return [];
}

1) 해시맵 생성 = numMap은 숫자와 그 숫자의 인덱스를 저장함
2) 루프를 통한 처리
- 현재숫자 nums[i]에 대해, target에서 nums[i]를 뺀 값을 complement로 계산한다
- complement가 numMap에 존재하는지 확인하고,
- 존재하면 complement와 현재 숫자가 목표 값을 만드는 쌍이므로 그 인덱스를 반환한다
- 존재하지 않으면 현재 숫자와 인덱스를 해시 맵에 추가한다
3) 해시 맵 사용 = 해시 맵을 사용하여 이전에 본 숫자들을 빠르게 확인할 수 있다

이 방식은 배열을 한번만 순회하기에 시간효율성이 좋다. 아 코드는 nums배열에서 두 숫자의 인덱스를 찾아 target에 맞는 쌍을 반환한다

 

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유