LeetCode발행일 2025. 3. 5.원본 https://blog.naver.com/jword_/223785004937 ↗

one-way search인줄 알았던 투 포인터(two pointer)

one-way search인줄 알았던 투 포인터(two pointer) — #LeetCode #one-waysearch #개발자의도구들 #투포인터 #twopointer only 파이썬 목표 참고 : 여기 one-wa...

#LeetCode#Naver Blog

#LeetCode #one-waysearch #개발자의도구들 #투포인터 #twopointer

​

​

  • only 파이썬
  • 목표 참고 : 여기

one-way search 응용하기

LeetCode(medium 11. Container With Most Water) 57.2%

  • 이전글에서 공부했었던 O(n²)인 것 같은데 O(n)으로 해결 가능한 문제이다.
  • 문제에서 요구하는 최대, 최솟값을 어떻게 활용할지 잘 파악하는게 중요하다.
text 코드 예제
                                    🤔 O(n²)으로 빠르게 구현이가능하다. 하지만 입력값이 10만이다.
>>> 이런 경우 보통 O(nlogn)으로 변환하는데 이 문제는 이걸 요구하는게 아니다.

>>> 한번의 search로 문제에서 요구하는 것을 구해야한다.

특징을 파악해보자.

text 코드 예제
                                    [1,8,6,2,5,4,8,3,7]
>>>>>> 이동하면서 문제에서 요구되는 값을 갱신해야한다.

✅ 요구사항: 넓이 x 높이가 최대가 되는 값은?

✅ 특징정리:
>>> 넓이: 1씩 증가한다 (자동으로)
>>> 높이: 최소값을 기준으로 갱신된다.
yaml 코드 예제
                                    ⚒️ 예시 체크
넓이 : idx 값의 차이
높이 : 최소 높이

# 1 (init)
[1,8,6,2,5,4,8,3,7]
 n m

width = 1
height = 1(1) = min(s,e)
result = width * height

# 2 (idx = 2)
     v
[1,8,6,2,5,4,8,3,7]
 n m

>>> have 2 case
     v
[1,8,6,2,5,4,8,3,7]

result = max(1 * 2, 6 * 1)
is it best option ? maybe...

# 3 (idx = 3)
            v
now :[1,8,6,2,5,4,8,3,7]
        m n

>>> 2 case
[1,8,6,2,5,4,8,3,7]
   m   n
     m n

result = max(result, 2 * 2, 2 * 1)

# 4 (idx = 4)
             v
now: [1,8,6,2,5,4,8,3,7]
        m n
>>>
        m     n
            n m

result = max(result, 3 * 5, ❌2 * 1 -> max값을 변경할 이유가 없다.)

# 5
                v
now: [1,8,6,2,5,4,8,3,7]
        m     n
>>>
        m       n

result = max(result, 4 * 4)

# 6
n                 v
now: [1,8,6,2,5,4,8,3,7]
        m       n
>>>
        m         n
result = max(result, 5 * 8)

# 7
                     v
now : [1,8,6,2,5,4,8,3,7]
         m           n
>>>
result = max(result, 6 * 3)

# 8
                       v
now : [1,8,6,2,5,4,8,3,7]
         m           n
>>>      m              n

result = max(result, 7 * 7)

result = 49

1차 결론

text 코드 예제
                                    ✅ init
>>> result
>>> min
>>> max 설정

✅ max는 언제 초기화되는가?
>>> max의 초기화는 의미가 없는 듯하다.
>>> 어차피 max를 초기화해도 min값이 높이를 결정하기 때문
>>> max보다는 fixed로 정하는게 나은거 같다.

✅ min은 언제 초기화 되는가?
>>> min은 그 값을 손해보더라도, 늘어나는 width값이 그 차이를 메꿀 수 있다면 언제든 초기화할 것
python 코드 예제
                                    class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """

        # init
        min_height = min(height[0], height[1])
        cur_width = 1
        acc_width = 0
        fixed = 0
        result = cur_width * min_height

        for i, h in enumerate(height):
            print("i:", i)
            # skip first
            if i == 0 or i == 1:
                continue

            # test
            # current, width + 1 min set , width, min_set

            result = max(result, (cur_width + 1 ) * min(min_height, h), cur_width * h)
            if result == (cur_width + 1 ) * min(min_height, h):
                min_height = h
                cur_width += 1

            elif result == cur_width * h:
                min_height = h

            print(min_height, cur_width)

        return result
  • 틀렸다...
  • 접근 자체가 잘못된 것 같다.

​

Two pointer

feat. gpt-o3

이 문제는 Two Pointer 문제였다. 계속 한방향 탐색에 집착한 나머지 이상항 수학공식을 억지로 만들다가 결국 실패했다...

text 코드 예제
                                    ✅ 양쪽 끝에서 시작한다.

✅ 갱신이 되어야할 대상 = 최소 height 값이다.
>>> 작은쪽의 point를 계속해서 옮기고, 두 포인터가 겹칠때 까지 계속한다.

수학으로 증명하기

python 코드 예제
                                    class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """

        # init
        l = 0
        r = len(height) - 1
        result = 0

        while l != r:
            width = r - l
            result = max(result, width * min(height[l], height[r]))
            print(result)

            if height[l] > height[r]:
                r -= 1
            else:
                l += 1

        return result
  • claer time: 2hour...
  • time beats: 5.04% 1297ms

배열 탐색 정리

여러 배열 탐색을 풀어보면서 여러가지 전략들을 떠올릴 수 있을 것 같다. 마치 드래곤볼을 모으듯이 말이다.

​

  • O(n²)이 가능한지?
  • 입력값이 충분히 작아야한다.
  • O(nlogn)
  • 정렬이 의미가 있는 경우
  • O(n)
  • 최대, 최소값을 업데이트 해가면서 구한다.
  • 눈치가 중요하다.
  • two pointer 기법이 있다.
  • palindrome인 경우
  • linkeList면 recursive로 reverse 시켜야함
  • 가장 긴걸 찾으려면
  • 전용 알고리즘 (hard)

​

​

후기

기존에 접하지 않은 전략들을 맛보닌깐 많이 당황스럽다. 그래도 포기하지는 말자. 하나씩 해결법을 모으는게 중요하다.