반응형

[JavaScript & TypeScript] Math.max()와 slice() 완벽 정리

📌 JavaScript & TypeScript에서 Math.max()와 slice() 활용하기

JavaScript와 TypeScript에서 배열의 최대값을 찾는 Math.max()와 배열을 자르는 slice()는 자주 사용되는 핵심 메서드입니다. 이 글에서는 각 메서드의 동작 방식과 최적의 활용법을 정리합니다. 🚀


✅ 1️⃣ Math.max() - 배열의 최대값 찾기

📌 기본 사용법

Math.max()는 주어진 숫자 중 가장 큰 값을 반환합니다.

console.log(Math.max(1, 5, 3, 7)); // 출력: 7

📌 배열에서 최대값 찾기 (Spread Operator 활용)

배열을 전달하려면 Spread Operator(...)를 사용해야 합니다.

const numbers = [3, 7, 2, 8, 5];
const maxVal = Math.max(...numbers);
console.log(maxVal); // 출력: 8

장점:

  • 직관적이고 코드가 간결함
  • 작은 배열에서는 효과적

단점:

  • 배열 크기가 클 경우 스택 오버플로우 위험 (Math.max(...largeArray))

📌 reduce()를 활용한 최대값 찾기 (안전한 방법)

큰 배열에서는 reduce()를 사용하면 안정적입니다.

const maxVal = numbers.reduce((max, num) => Math.max(max, num), -Infinity);
console.log(maxVal); // 출력: 8

대량 데이터에서도 안전하게 실행 가능! 🚀


✅ 2️⃣ slice() - 배열 일부 잘라내기

📌 기본 사용법

slice(start, end)는 start부터 end-1까지의 요소를 복사하여 새로운 배열을 생성합니다.

const arr = [0, 1, 2, 3, 4, 5];
console.log(arr.slice(1, 4)); // 출력: [1, 2, 3]

📌 slice()의 특징

메서드 원본 배열 변경 여부 반환 값

slice(start, end) ❌ 변경되지 않음 새로운 배열
splice(start, deleteCount, ...items) ✅ 변경됨 삭제된 요소 반환

즉, slice()는 원본 배열을 유지하며 부분 배열을 만들 때 사용

📌 slice()를 활용한 배열 복사

const original = [1, 2, 3, 4];
const copy = original.slice();
console.log(copy); // 출력: [1, 2, 3, 4]

배열을 변경하지 않고 복사할 때 slice() 사용 가능!


📌 Math.max()와 slice()를 함께 활용한 예제

🚀 LeetCode 문제 해결 (배열 내 최댓값 찾기)

const arr = [3, 7, 1, 9, 4, 2];
const maxInSubarray = Math.max(...arr.slice(1, 5));
console.log(maxInSubarray); // 출력: 9 (1~4번 인덱스에서 최댓값)

배열의 특정 부분에서 최대값을 찾을 때 Math.max(...slice()) 조합 활용 가능!


📌 최종 정리

🚀 Math.max() 요약

  • 단일 값의 최대값 찾기: Math.max(a, b, c, ...)
  • 배열의 최대값 찾기 (Spread Operator 사용): Math.max(...arr)
  • 대량 데이터 처리 시 안전한 방법: arr.reduce((max, num) => Math.max(max, num), -Infinity)

🚀 slice() 요약

  • 배열 일부 가져오기: arr.slice(start, end) → end는 포함되지 않음
  • 배열 복사: arr.slice()
  • splice()와 다름 (원본 배열 변경 X)

이제 Math.max()와 slice()를 활용하여 더 효율적인 코드 작성이 가능! 🚀

 

반응형
반응형

[LeetCode] Trapping Rain Water - 효율적인 해결 방법 (Two Pointers)

📌 문제 설명

LeetCode의 "Trapping Rain Water" 문제는 높이 배열(height[])이 주어질 때, 빗물이 고일 수 있는 총량을 계산하는 문제입니다.

  • height[i]: 각 기둥의 높이
  • 각 기둥의 너비는 1로 고정
  • 빗물이 얼마나 고일 수 있는지 계산해야 함

📌 문제 해결 과정

✅ 잘못된 접근 (Brute Force, O(N²))

모든 인덱스에서 왼쪽 최대(leftMax)와 오른쪽 최대(rightMax) 를 찾아 빗물을 계산하는 방법이 떠오를 수 있습니다.

export function trap(height: number[]): number {
  let water = 0;

  for (let i = 1; i < height.length - 1; i++) {
    const leftMax = Math.max(...height.slice(0, i + 1));
    const rightMax = Math.max(...height.slice(i));

    water += Math.max(0, Math.min(leftMax, rightMax) - height[i]);
  }

  return water;
}

🚨 문제점:

  • Math.max(...arr)를 반복 호출해야 하므로 시간 복잡도 O(N²) 발생
  • 배열이 길어질수록 매우 비효율적

📌 최적화된 해결 방법 (Two Pointers, O(N))

💡 핵심 아이디어: "양쪽에서 중앙으로 이동하며 작은 쪽을 기준으로 계산"

  1. leftMax와 rightMax를 유지하면서 한 번의 순회로 해결
  2. 작은 쪽(leftMax 또는 rightMax)을 기준으로 물을 계산
  3. 양쪽 끝에서 중앙으로 이동하면서 빗물을 계산 (O(N))

작은 쪽을 기준으로 계산하는 이유:

  • leftMax < rightMax라면 leftMax보다 높은 곳이 나오기 전까지 leftMax가 현재 위치에서 최대 물 저장 가능 높이
  • 반대로 rightMax < leftMax라면 rightMax가 현재 위치에서 최대 물 저장 가능 높이

📌 최적화된 코드 (O(N))

export function trap(height: number[]): number {
  let left = 0, right = height.length - 1;
  let leftMax = 0, rightMax = 0;
  let water = 0;

  while (left < right) {
    if (height[left] < height[right]) {
      leftMax = Math.max(leftMax, height[left]);
      water += leftMax - height[left];
      left++;
    } else {
      rightMax = Math.max(rightMax, height[right]);
      water += rightMax - height[right];
      right--;
    }
  }

  return water;
}

📌 예제 분석

입력:

height = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1];

Step-by-step 실행 과정

left right leftMax rightMax water 설명

0 11 0 1 0 height[left] < height[right], 왼쪽 이동
1 11 1 1 0 height[left] >= height[right], 오른쪽 이동
1 10 1 2 0 height[left] < height[right], 왼쪽 이동
2 10 1 2 1 water += 1 - height[2]
3 10 2 2 1 height[left] >= height[right], 오른쪽 이동
3 9 2 2 2 water += 2 - height[9]
3 8 2 2 2 height[left] >= height[right], 오른쪽 이동
3 7 2 3 2 height[left] < height[right], 왼쪽 이동

최종 결과: 6 (가둘 수 있는 물의 양)


📌 시간 복잡도 분석

접근법 시간 복잡도 설명

Brute Force (O(N²)) O(N²) 매번 Math.max() 호출로 인해 비효율적
Two Pointers (O(N)) O(N) 한 번의 순회만으로 해결

Two Pointers 사용하면 O(N)으로 해결 가능! 🚀


📌 최종 정리

  1. 각 위치에서 고일 수 있는 물의 양 = min(leftMax, rightMax) - height[i]
  2. 모든 인덱스에서 leftMax와 rightMax를 찾는 것은 O(N²)로 비효율적
  3. "양쪽 끝에서 중앙으로 이동하면서 작은 쪽을 기준으로 물을 계산"하면 O(N)으로 해결 가능
  4. O(N) 탐욕법(Two Pointers)로 해결 가능!

💡 이제 비슷한 문제에서 "양쪽에서 중앙으로 이동하는 방식"을 떠올려 보세요! 🚀

 

반응형

+ Recent posts