<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>부부의 코딩 성장 일기</title>
    <link>https://codingbubu.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Mon, 13 Jul 2026 01:38:28 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>펩시_콜라</managingEditor>
    <item>
      <title>LeetCode 383(Ransom Note, Python)</title>
      <link>https://codingbubu.tistory.com/163</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;1. 문제 링크&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/ransom-note/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://leetcode.com/problems/ransom-note/&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1709454908314&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Ransom Note - LeetCode&quot; data-og-description=&quot;Can you solve this real interview question? Ransom Note - Given two strings ransomNote and magazine, return true if ransomNote can be constructed by using the letters from magazine and false otherwise. Each letter in magazine can only be used once in ranso&quot; data-og-host=&quot;leetcode.com&quot; data-og-source-url=&quot;https://leetcode.com/problems/ransom-note/&quot; data-og-url=&quot;https://leetcode.com/problems/ransom-note/description&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bptBVs/hyVuiKcZ4v/4k2ccTajeTZjaTnPOkumHk/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/ransom-note/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://leetcode.com/problems/ransom-note/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bptBVs/hyVuiKcZ4v/4k2ccTajeTZjaTnPOkumHk/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Ransom Note - LeetCode&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Can you solve this real interview question? Ransom Note - Given two strings ransomNote and magazine, return true if ransomNote can be constructed by using the letters from magazine and false otherwise. Each letter in magazine can only be used once in ranso&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;leetcode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;2. 문제 설명&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;두 문자열 ransomNote, magazine이 주어졌을 때 magazine의 문자열을 이용하여 ransomNote를 만들어낼 수 있는 지 True, False 반환하는 문제&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;문자열의 순서는 자유롭게 바꿀 수 있으며 magazine에 문자열은 한 번씩 사용 가능하다. a가 두 개 있으면 두 번까지, 하나 있으면 한 번만 사용할 수 있음.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;예시1) ransomNote = &quot;a&quot;, magazine = &quot;b&quot; 이면 False&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;예시2) ransomNote = &quot;aa&quot;, magazine = &quot;ab&quot;이면 False&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;예시3) ransomNote = &quot;aa&quot;, magazine = &quot;aab&quot;이면 True&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;3. 처음 풀이&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;ransomNote와 magazine의 각 문자의 등장 횟수를 세기 위해 딕셔너리 check1과 check2 생성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;ransomNote의 각 문자를 순회하면서 해당 문자의 등장 횟수를 check1에 기록&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;magazine의 각 문자를 순회하면서 해당 문자의 등장 횟수를 check2에 기록&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;check1에 등장한 각 문자와 그 등장 횟수를 순회하면서 해당 문자가 check2에도 있고, 그 등장 횟수가 충분하면 계속 진행하고, 아니라면 False를 반환. 모든 문자에 대해 확인이 끝나면 True를 반환&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -&amp;gt; bool:
        check1 = {}  # ransomNote의 각 문자의 등장 횟수를 저장하기 위한 딕셔너리
        check2 = {}  # magazine의 각 문자의 등장 횟수를 저장하기 위한 딕셔너리

        # ransomNote의 각 문자의 등장 횟수를 계산하여 check1에 저장
        for s in ransomNote:
            if s in check1:
                check1[s] = check1[s] + 1
            else:
                check1[s] = 1

        # magazine의 각 문자의 등장 횟수를 계산하여 check2에 저장
        for s in magazine:
            if s in check2:
                check2[s] = check2[s] + 1
            else:
                check2[s] = 1
        
        # ransomNote의 각 문자와 그 등장 횟수를 magazine에서 확인
        for key in check1:
            if key not in check2:  # magazine에 해당 문자가 없으면 조건 불만족
                return False
            elif check1[key] &amp;gt; check2[key]:  # magazine에 해당 문자의 등장 횟수가 부족하면 조건 불만족
                return False
        
        return True  # 모든 조건을 만족하면 ransomNote를 만들 수 있음&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;4. 다른 풀이&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;ransomNote의 각 문자를 magazine에서 찾아 제거하는 방식으로 접근. replace 메서드를 사용하여 문자를 찾아 제거. magazine에 해당 문자가 없으면 False&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;replace를 할 때 문자열이 새로 생겨나서 공간 복잡도 측면에서 효율적이지 못함.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -&amp;gt; bool:
        for c in ransomNote:
            if c in magazine:
                magazine = magazine.replace(c, '', 1)
            else:
                return False
        return True&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;collections 모듈의 Counter 클래스를 사용하여 ransomNote의 각 문자의 등장 횟수와 magazine에서 해당 문자의 등장 횟수를 비교하여 충분한 지 확인.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -&amp;gt; bool:
        # ransomNote에서 중복을 제거한 문자 집합 생성
        unique_characters = set(ransomNote) 

        # 각 문자에 대해 magazine과 ransomNote에서의 등장 횟수 비교
        for char in unique_characters:
            if magazine.count(char) &amp;lt; ransomNote.count(char):
                # ransomNote에서의 등장 횟수가 더 많으면 False 반환하고 반복 종료
                return False
                break
        
        # 모든 문자에 대해 등장 횟수가 충분하면 True 반환
        return True

&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;5. 배운 점&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;Counter 라이브러리를 적극적으로 활용하자.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;**Counter**는 Python의 내장 모듈인 **collections**에 포함된 클래스로, 주어진 순회 가능한(iterable) 객체의 각 요소의 개수를 셈. 주로 리스트, 튜플, 문자열 등과 같은 iterable한 데이터에 대해 각 요소의 빈도를 계산하는 데 사용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;사용 예시&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;from collections import Counter

# 리스트에서 각 요소의 개수 세기
my_list = [1, 2, 3, 1, 2, 1, 4, 5, 4]
counter_list = Counter(my_list)
print(counter_list)
# 출력: Counter({1: 3, 2: 2, 4: 2, 3: 1, 5: 1})

# 문자열에서 각 문자의 개수 세기
my_string = &quot;hello&quot;
counter_string = Counter(my_string)
print(counter_string)
# 출력: Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1})

&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Algorithm/LeetCode</category>
      <category>383번</category>
      <category>collections</category>
      <category>Counter</category>
      <category>leetcode</category>
      <category>leetcode 383</category>
      <category>Ransom</category>
      <category>replace</category>
      <category>리트코드</category>
      <author>제로_콜라</author>
      <guid isPermaLink="true">https://codingbubu.tistory.com/163</guid>
      <comments>https://codingbubu.tistory.com/163#entry163comment</comments>
      <pubDate>Sun, 31 Mar 2024 19:00:33 +0900</pubDate>
    </item>
    <item>
      <title>LeetCode 146(LRU Cache, Python)</title>
      <link>https://codingbubu.tistory.com/155</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;1. 문제 링크&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://leetcode.com/problems/lru-cache/description/&quot;&gt;LRU Cache - LeetCode&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1709369627923&quot; style=&quot;color: #333333; text-align: start;&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cf5Y1s/hyVqlaB68g/IR93Tkejhlie6pKdU2H7AK/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260&quot; data-og-url=&quot;https://leetcode.com/problems/lru-cache/description&quot; data-og-source-url=&quot;https://leetcode.com/problems/lru-cache/description/&quot; data-og-host=&quot;leetcode.com&quot; data-og-description=&quot;Can you solve this real interview question? LRU Cache - Design a data structure that follows the constraints of a Least Recently Used (LRU) cache [https://en.wikipedia.org/wiki/Cache_replacement_policies#LRU]. Implement the LRUCache class: * LRUCache(int c&quot; data-og-title=&quot;LRU Cache - LeetCode&quot; data-og-type=&quot;website&quot; data-ke-align=&quot;alignCenter&quot; data-ke-type=&quot;opengraph&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://leetcode.com/problems/lru-cache/description/&quot; data-source-url=&quot;https://leetcode.com/problems/lru-cache/description/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cf5Y1s/hyVqlaB68g/IR93Tkejhlie6pKdU2H7AK/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;LRU Cache - LeetCode&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;Can you solve this real interview question? LRU Cache - Design a data structure that follows the constraints of a Least Recently Used (LRU) cache [https://en.wikipedia.org/wiki/Cache_replacement_policies#LRU]. Implement the LRUCache class: * LRUCache(int c&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;leetcode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;2. 문제 설명&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;주어진 연산을 수행하는 LRU(Least Recently Used) 캐시를 구현하기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;LRU 캐시가 지원해야하는 두 가지 연산은 다음과 같다.&amp;nbsp;&lt;/span&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;get(key)&lt;/b&gt;: 캐시에서 특정 키(&lt;b&gt;key&lt;/b&gt;)에 대응하는 값 반환(사용O). 만약 해당 키가 캐시에 없다면 -1을 반환(이건 사용X).&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;put(key, value)&lt;/b&gt;: 캐시에 값을 입력(사용O). 만약 캐시가 가득 차 있으면, 가장 오랫동안 사용되지 않은(Least Recently Used) 항목을 제거하고 새로운 값을 삽입&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;3. 처음 풀이&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;get&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;메서드는 주어진 키를 찾아 해당 값을 가져오기. 키가 존재하면 해당 키-값 쌍을 memo에서 삭제 후 다시 추가하여 최근 사용된 것으로 갱신&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;put&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;메서드는 주어진 키-값을 memo에 추가. 이미 존재하는 키라면 해당 키-값 쌍을 삭제 후 새로운 값을 추가하여 최근 사용된 것으로 갱신. 또한, 캐시의 크기가 용량을 초과하면 가장 오래된 항목을 삭제&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;이때, 일반적인 dictionary를 사용해도 되지만 이전 버전의 파이썬에서는 dictionary의 순서가 보장되지 않기 때문에 순서가 있는 딕셔너리임을 명시적으로 밝혀주기 위해 OrderedDict을 사용하였음.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;ruby&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;from collections import OrderedDict

class LRUCache:
    def __init__(self, capacity: int):
        # OrderedDict를 사용하여 키-값 쌍을 유지하는 memo 초기화
        self.memo = OrderedDict()
        # 캐시의 최대 크기 설정
        self.capacity = capacity

    def get(self, key: int) -&amp;gt; int:
        # 주어진 키가 memo에 없으면 -1 반환
        if key not in self.memo:
            return -1
        # 키에 해당하는 값을 가져와서 해당 키-값 쌍을 memo에서 제거 후 다시 추가 (갱신)
        value = self.memo[key]
        del self.memo[key]
        self.memo[key] = value
        return self.memo[key]
            
    def put(self, key: int, value: int) -&amp;gt; None:
        # 이미 존재하는 키라면 해당 키-값 쌍을 삭제
        if key in self.memo:
            del self.memo[key]
        # 새로운 키-값 쌍을 memo에 추가
        self.memo[key] = value
        # 캐시의 크기가 용량을 초과하면 가장 오래된 항목 삭제
        if len(self.memo) &amp;gt; self.capacity:
            del self.memo[next(iter(self.memo))]

# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)&lt;/code&gt;&lt;/pre&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;4. 다른 풀이&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;OrderedDict.move_to_end(key) 메소드를 이용하면 삭제 후 추가하지 않아도 최근 요소로 갱신이 가능하다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;popitem()은 기본적으로 후입선출 방식이지만 인자에 False를 전달하면 선입선출이 가능하다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;ruby&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot;&gt;&lt;code&gt;class LRUCache:

    def __init__(self, capacity: int):
        self.capacity = capacity
        self.dict = OrderedDict()

    def get(self, key: int) -&amp;gt; int:
        if key not in self.dict:
            return -1
        
        self.dict.move_to_end(key)
        return self.dict[key]

    def put(self, key: int, value: int) -&amp;gt; None:
        if key in self.dict:
            self.dict.move_to_end(key)
        
        self.dict[key] = value
        if len(self.dict) &amp;gt; self.capacity:
            self.dict.popitem(False)

# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;5. 배운 점&lt;/span&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;OrderedDict&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;OrderedDict는 파이썬의 내장 모듈인 collections에서 제공되는 클래스, 순서가 있는 딕셔너리&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;일반적인 딕셔너리는 파이썬 3.7 이전의 버전에서는 순서가 보장되지 않음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그러나 파이썬 3.7 이상에서는 일반 딕셔너리도 삽입 순서를 유지. 그럼에도 다른 차이점이 있음.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;OrderedDict 만의 메서드가 있다. 예를들어&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;move_to_end()&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;메서드를 사용하여 특정 항목을 딕셔너리의 끝으로 이동시킬 수 있음.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Equality 검사를 할 때 일반 dictionary는 요소의 값의 일치만 확인하며, OrderedDict은 순서까지 동등성을 확인함.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;routeros&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot;&gt;&lt;code&gt;from collections import OrderedDict

# 일반적인 딕셔너리
normal_dict = {'banana': 3, 'apple': 1, 'orange': 2}
print(&quot;Normal Dict:&quot;, normal_dict)  # 출력 결과: {'banana': 3, 'apple': 1, 'orange': 2}

# OrderedDict
ordered_dict = OrderedDict([('banana', 3), ('apple', 1), ('orange', 2)])
print(&quot;OrderedDict:&quot;, ordered_dict)  # 출력 결과: OrderedDict([('banana', 3), ('apple', 1), ('orange', 2)])

# 항목 추가
normal_dict['grape'] = 4
ordered_dict['grape'] = 4

print(&quot;\\nAfter Adding 'grape':&quot;)
print(&quot;Normal Dict:&quot;, normal_dict)  # 출력 결과: {'banana': 3, 'apple': 1, 'orange': 2, 'grape': 4}
print(&quot;OrderedDict:&quot;, ordered_dict)  # 출력 결과: OrderedDict([('banana', 3), ('apple', 1), ('orange', 2), ('grape', 4)])

# move_to_end 메서드 사용
ordered_dict.move_to_end('apple')  # 'apple' 항목을 끝으로 이동

print(&quot;\\nAfter Moving 'apple' to the End in OrderedDict:&quot;)
print(&quot;OrderedDict:&quot;, ordered_dict)  # 출력 결과: OrderedDict([('banana', 3), ('orange', 2), ('grape', 4), ('apple', 1)])

# Equality 검사
equal_check = normal_dict == dict(ordered_dict)
print(&quot;\\nEquality Check:&quot;, equal_check)  # 출력 결과: False

&lt;/code&gt;&lt;/pre&gt;
&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;next(iter())는 두 가지 함수를 조합하여 사용하는 구문&lt;/span&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;iter() 함수:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;객체를 이터레이터로 변환&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;next() 함수:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이터레이터에서 다음 값을 가져옴. 만약 끝에 도달했다면 StopIteration 예외가 발생, 이때 두 번째 인수로 전달된 기본 값이 있으면 그 값을 반환&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;makefile&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;my_list = [1, 2, 3, 4, 5]
my_iterator = iter(my_list)

# 첫 번째 호출
result1 = next(my_iterator)
print(result1)  # 출력 결과: 1

# 두 번째 호출
result2 = next(my_iterator)
print(result2)  # 출력 결과: 2&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;popitem() 메서드는 딕셔너리에서 항목을 제거하고 반환, 일반적으로 인자 없이 사용. 하지만 파이썬 3.9부터는 last=True(기본값) 또는 last=False를 인자로 사용 가능. True(기본값)은 후입선출, False는 선입선출&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Algorithm/LeetCode</category>
      <category>146번</category>
      <category>cache</category>
      <category>dictionary</category>
      <category>Least Recently Used</category>
      <category>LeetCode 146</category>
      <category>LRU</category>
      <category>move_to_end</category>
      <category>OrderedDict</category>
      <category>popitem()</category>
      <category>리트코드</category>
      <author>제로_콜라</author>
      <guid isPermaLink="true">https://codingbubu.tistory.com/155</guid>
      <comments>https://codingbubu.tistory.com/155#entry155comment</comments>
      <pubDate>Sat, 30 Mar 2024 19:00:45 +0900</pubDate>
    </item>
    <item>
      <title>LeetCode 143(Reorder List, Python)</title>
      <link>https://codingbubu.tistory.com/153</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 문제 링크&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://leetcode.com/problems/reorder-list/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://leetcode.com/problems/reorder-list/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 문제 설명&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;linked list의 head가 주어졌을 때, 해당 list를 아래처럼 표현할 수 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;L0 &amp;rarr; L1 &amp;rarr; ... &amp;rarr; Ln-1 &amp;rarr; Ln&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이 때, 아래의 형태가 되도록 list를 reorder해라.&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;L0 &amp;rarr; Ln &amp;rarr; L1 &amp;rarr; Ln-1 &amp;rarr; L2 &amp;rarr; Ln-2 &amp;rarr; ...&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;여기서 node의 value자체를 수정하는 것이 아니라, node의 연결관계를 바꿔야 한다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;예시1)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;head가 [1,2,3,4]로 1&amp;rarr;2&amp;rarr;3&amp;rarr;4의 연결관계를 가지고 있다면,&amp;nbsp;&lt;/li&gt;
&lt;li&gt;1&amp;rarr;4&amp;rarr;2&amp;rarr;3으로 변경할 수 있다. output = [1,4,2,3]&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;예시2)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;head가 [1,2,3,4,5]로 1&amp;rarr;2&amp;rarr;3&amp;rarr;4&amp;rarr;5의 연결관계를 가지고 있다면,&lt;/li&gt;
&lt;li&gt;1&amp;rarr;5&amp;rarr;2&amp;rarr;4&amp;rarr;3으로 변경이 된다. output = [1,5,2,4,3]&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 처음 풀이&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결국 더 좋은 방법을 찾지 못해서, time limit에 걸린채로 마무리하고.. 다른 풀이를 참고하였다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;a,b,c 세개의 커서를 만들어주고, c는 가장 오른쪽으로 옮겨서 가장 끝의 노드로 위치시킨다음에,&lt;/li&gt;
&lt;li&gt;a.next에 c를 붙이고, 그 next에 b를 붙이는 방식을 반복하였다.&lt;/li&gt;
&lt;li&gt;[1,2,3,4,5]가 있을 때, 각 Iteration을 돌때마다 아래처럼 head의 연결관계가 변경이 된다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;[1,5,2,3,4]&amp;nbsp;&lt;/li&gt;
&lt;li&gt;[1,5,2,4,3]&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;하지만 여기서 문제는,, iteration돌 때마다, 계속 while문으로 c를 맨 끝으로 이동시켜야 하고,&amp;nbsp;&lt;/li&gt;
&lt;li&gt;node를 많이 가지고 있는 head에 대해서는 너무 비효율적이다. 12개 test중에 1개 통과를 못했는데,, 그것의 head는 아래처럼 생겼다.&amp;nbsp;아래는 time limit 걸린 로직&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-03-02 오전 10.48.56.png&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;1056&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVt56R/btsFoEQPCD9/71AsRi9AFEs1tkFGMnEmik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVt56R/btsFoEQPCD9/71AsRi9AFEs1tkFGMnEmik/img.png&quot; data-alt=&quot;submission 통과 못할만 하다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVt56R/btsFoEQPCD9/71AsRi9AFEs1tkFGMnEmik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVt56R%2FbtsFoEQPCD9%2F71AsRi9AFEs1tkFGMnEmik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;253&quot; height=&quot;299&quot; data-filename=&quot;스크린샷 2024-03-02 오전 10.48.56.png&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;1056&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;submission 통과 못할만 하다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1709343984532&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reorderList(self, head: Optional[ListNode]) -&amp;gt; None:
        &quot;&quot;&quot;
        Do not return anything, modify head in-place instead.
        &quot;&quot;&quot;

        if not head:
            return head 

        if not head.next:
            return head

        a,b,c= head,head.next,head

        c_distance =0

        while c.next:
            c = c.next
            c_distance += 1

        while b.next:

            a.next = c            
            c.next = b

            a=b
            b=b.next

            c_count = 0
            while c_count &amp;lt; c_distance-1:
                c = c.next
                c_count +=1
            
            c_distance = c_count-1 # reset c_distance 
        
            c.next = None&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 다른 풀이&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결국 다른 풀이를 참고하게 되었다. 3가지 step으로 나눠서 코드를 작성하는데, 이것 모두 linked list에서 배운 것들이다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그것들을 총집합시킨 문제..였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;step1) slow, fast를 통해 head의 중간 node를 찾는다. [1,2,3,4,5,6]이라면, slow node의 head가 4에 위치할 수 있도록&lt;/li&gt;
&lt;li&gt;step2) [1,2,3], [4,5,6] 두개로 분리하고, 두번째 list에 대해 거꾸로 뒤집는다. [1,2,3], [6,5,4]가 될 수 있도록
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Revsered Linked List: &lt;a href=&quot;https://codingbubu.tistory.com/99&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://codingbubu.tistory.com/99&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;step3) 분리된 [1,2,3], [6,5,4] linked list에 대해&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1&amp;rarr;6&amp;rarr;2&amp;rarr;5&amp;rarr;3&amp;rarr;4가 되도록 연결관계를 짓는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;step1) find middle
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;slow, fast = head, head로 저장하고,&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;slow는 한칸씩 next로 이동시키고&lt;/li&gt;
&lt;li&gt;fast는 두칸씩 next에 이동시키다 보면 slow는 중간 지점으로 이동이 된다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;step2) reverse second half
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;뒤집은 것은 아직도 약간 헷갈리는데 아래 그림을 보면 이해가 쉽다.&lt;/li&gt;
&lt;li&gt;결국 앞에 None을 하나 만들어서 None&amp;rarr;1&amp;rarr;2&amp;rarr;3&amp;rarr;4&amp;rarr;5 가 5&amp;rarr;4&amp;rarr;3&amp;rarr;2&amp;rarr;1&amp;rarr;None이 되도록 작업하는 것.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-03-02 오전 10.56.59.png&quot; data-origin-width=&quot;1374&quot; data-origin-height=&quot;820&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eQCiS5/btsFoEJ28rV/SxsM07BHNydNdlRbT4ort1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eQCiS5/btsFoEJ28rV/SxsM07BHNydNdlRbT4ort1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eQCiS5/btsFoEJ28rV/SxsM07BHNydNdlRbT4ort1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeQCiS5%2FbtsFoEJ28rV%2FSxsM07BHNydNdlRbT4ort1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;655&quot; height=&quot;391&quot; data-filename=&quot;스크린샷 2024-03-02 오전 10.56.59.png&quot; data-origin-width=&quot;1374&quot; data-origin-height=&quot;820&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;step3) merge lis
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;분리된 [1,2,3], [4,5,6]을 각각 head1, head2라고 하였을 때,
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;head1의 다음 노드를 nxt에 keep해두고,&lt;/li&gt;
&lt;li&gt;head1의 다음노드를 head2로 설정하여, 연결리스트를 병합한 뒤,&lt;/li&gt;
&lt;li&gt;head1를 head2로 이동을 시켜서, 다음 iteration에서 head1이 새로운 연결리스트의 끝을 가리키도록 한다.&lt;/li&gt;
&lt;li&gt;그리고 head2를 다음 노드로 이동시켜서, 다음 iteration에서 head2가 새로운 연결리스트의 끝을 가리키도록 한다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;[1,2,3], [4,5,6]이 다음과 같이 반복이 되면,&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;첫 iteration에서 head1: 1&amp;rarr;6&amp;rarr;2&amp;rarr;3, head2: 5&amp;rarr;4&lt;/li&gt;
&lt;li&gt;두번째 iteration에서 head1: 1&amp;rarr;6&amp;rarr;2&amp;rarr;5&amp;rarr;3, head2: 4&lt;/li&gt;
&lt;li&gt;마지막 iteration에서 head1: 1&amp;rarr;6&amp;rarr;2&amp;rarr;5&amp;rarr;3&amp;rarr;4, head2: None이되고,&lt;/li&gt;
&lt;li&gt;while문이 head2가 존재할 때까지만 반복하므로 iteration이 종료된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709344538701&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution:
    def reorderList(self, head):
        if not head:
            return 

        #step 1: find middle            
        slow, fast = head, head
        while fast.next and fast.next.next:
            slow = slow.next
            fast = fast.next.next
        
        #step 2: reverse second half
        prev, curr = None, slow.next

        while curr:
            nxt = curr.next
            curr.next = prev
            prev = curr
            curr = nxt
    
        slow.next = None
        
        #step 3: merge lists
        head1, head2 = head, prev
        while head2:
            nxt = head1.next            
            head1.next = head2
            head1 = head2
            head2 = nxt&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 배운 점&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;linked list에서 가장 헷갈렸던 부분이 아래처럼 구현하는 부분이었는데
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;nxt = head1.next&lt;/li&gt;
&lt;li&gt;head1.next = head2&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;nxt = head1.next는 그냥 'node'가 이동이 된다고 생각하고,&lt;/li&gt;
&lt;li&gt;head1.next = head2는 연결관계인 화살표가 바뀐다고 생각하니 편했다.&lt;/li&gt;
&lt;li&gt;이번 문제에서도 [1,2,3], [4,5,6]에 대해서 아래처럼 위 아래로 두고, 위에 nxt, h1, h2의 위치를 옮기고, next를 쓰면 화살표를 이동하는 구조로 작성하니 좀 더 이해가 쉬워졌다.&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;[1,2,3]&lt;/li&gt;
&lt;li&gt;[4,5,6]&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Algorithm/LeetCode</category>
      <category>LeetCode 143</category>
      <category>linked list</category>
      <category>Medium</category>
      <category>Python</category>
      <category>reorder list</category>
      <category>리트코드</category>
      <category>리트코드 143</category>
      <category>미디움</category>
      <category>연결리스트</category>
      <category>파이썬</category>
      <author>펩시_콜라</author>
      <guid isPermaLink="true">https://codingbubu.tistory.com/153</guid>
      <comments>https://codingbubu.tistory.com/153#entry153comment</comments>
      <pubDate>Fri, 29 Mar 2024 19:00:14 +0900</pubDate>
    </item>
    <item>
      <title>LeetCode 142(Linked List Cycle II, Python)</title>
      <link>https://codingbubu.tistory.com/156</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;1. 문제 링크&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/linked-list-cycle-ii/description/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://leetcode.com/problems/linked-list-cycle-ii/description/&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;2. 문제 설명&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;연결 리스트(Linked List)에서 순환(사이클)이 발생하는 경우, 순환의 시작 지점 노드를 반환하고, 사이클이 없으면 None 반환&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;3. 처음 풀이&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;노드를 한 칸씩 전진하며 set에 저장하고, 이미 들어있으면 그 노드를 반환. 끝까지 갈 동안 같은 노드가 나오지 않으면 사이클이 없으므로 return None&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;공간 복잡도 O(n)으로 좋지 않다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: Optional[ListNode]) -&amp;gt; Optional[ListNode]:
        memo = set()

        cur = head
        while cur:
            if cur in memo:
                return cur
            else:
                memo.add(cur)
                cur = cur.next
        return
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;더 고민해서 나온 좋은 풀이&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;head에서 3칸 이동하면 싸이클의 시작 지점이고, 싸이클의 길이가 5인 상황을 생각해보자.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;	0 -&amp;gt; 1 -&amp;gt; 2 -&amp;gt; 3(8) -&amp;gt; 4(9)
                   ↗             ↘ 
	             7(12) &amp;lt;- 6(11) &amp;lt;- 5(10)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;slow, fast가 head에서 출발하고 slow는 한 칸씩, fast는 두 칸씩 이동한다고 해보자. 사이클이 없다면 fast는 끝까지 가버리고, 사이클이 있다면 slow와 fast는 언젠가 만난다. (상대 속도가 한 칸이므로 언젠가 무조건 만난다.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;그러면 만났을 때를 생각해보면 slow가 x칸 갔을 때 fast는 2x칸 갔을 것이다. 위 상황에서는 5(10)에서 만난다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;여기서 5는 사이클의 길이 5와 같다&amp;hellip; 우연일까?&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;그렇지 않다. 몇 가지 상황을 더 관찰해보아도 그렇다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;물론 아닌 경우도 있다.(위의 상황과 반대로 5칸 이동 시 사이클 시작, 사이클 길이가 3인 경우 slow가 3칸 이동 시 아직 만나지 않는다. 하지만 3+3칸 가면 만난다.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;그 이유를 생각해보면 slow가 x칸, fast가 2x칸 이동했을 때 이동 거리의 차는 x이고 만나려면 주기의 길이 n으로 나누었을 때 그 값이 같아야 하므로 x를 n으로 나눈 나머지는 0이다. 따라서 x가 n, 2n, 3n, &amp;hellip; 일 때 만나게 된다.(n, 2n, 3n, &amp;hellip; 중 사이클 시작 지점까지 거리 보다 긴 값에서 만남)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;일반화해서 slow가 kn, fast가 2kn 칸 이동하여 만났다고 하자.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;그리고 위 상황에서 5(10)에서 만났을 때 또 재미있는 사실은, 사이클의 시작인 3(8)까지 3칸을 더 가면 되는데 이 3칸이 head에서 사이클 시작 지점까지의 길이도 3이라는 것이다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;그러니까 두 포인터가 5(10)에서 만난 순간 출발 지점 0에서 새로운 포인터를 출발시키면 새로운 포인터가 slow 포인터가 만나는 지점이 바로 사이클의 시작 지점인 3(8)이라는 것이다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;수학적으로 생각해보자. slow가 kn, fast가 2kn칸 이동해서 처음 만났다고 하고 head에서 사이클 시작 지점까지 p칸이라고 하자. 이때 slow가 p칸 더 이동하면 kn+p 만큼 이동하였다. 이를 다르게 생각하면 head로 부터 p칸 이동후 kn을 움직였으니 사이클을 k바퀴 돌고 제자리에 온다. 즉, 사이클이 시작되는 지점에 있게 된다. 말로해서 복잡해보이지만 수식으로 쓰면 간단하다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;요약하자면 slow, fast를 출발시키고 만나면, head에서 새로운 포인터를 출발시켜 slow와 만나는 지점, 그곳이 사이클의 시작 지점이다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: Optional[ListNode]) -&amp;gt; Optional[ListNode]:
        slow = fast = head
        
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                break
        
        if not fast or not fast.next:
            return
        
        slow = head
        
        while slow != fast:
            slow = slow.next
            fast = fast.next
        
        return slow
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;4. 다른 풀이&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;찾아본 다른 사람들의 풀이 모두 2번째 풀이와 같은 논리였음.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;5. 배운 점&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;Linked List에서 slow, fast 기법은 정말 유용하다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;간단한 상황을 많이 나열해보고 관찰하면서 규칙을 찾을 수 있었다. 수학문제와 마찬가지로 코드 역시 화면을 바라보며 생각하기보다 손으로 그림 그려보며 생각하는게 좋다. 간단한 상황으로 바꾸어 관찰하는게 도움이 된다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;관찰한 결과를 논리적으로 확신을 가질 때 수학적인 사고가 핵심적이었다. 코딩과 수학은 불가분의 관계이다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Algorithm/LeetCode</category>
      <category>142번</category>
      <category>Cycle</category>
      <category>Fast</category>
      <category>leetcode 142</category>
      <category>linked list</category>
      <category>Slow</category>
      <category>two pointers</category>
      <category>리트코드</category>
      <author>제로_콜라</author>
      <guid isPermaLink="true">https://codingbubu.tistory.com/156</guid>
      <comments>https://codingbubu.tistory.com/156#entry156comment</comments>
      <pubDate>Thu, 28 Mar 2024 19:00:08 +0900</pubDate>
    </item>
    <item>
      <title>LeetCode 374(Guess Number Higher or Lower, Python)</title>
      <link>https://codingbubu.tistory.com/150</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. 문제 링크&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://leetcode.com/problems/guess-number-higher-or-lower/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://leetcode.com/problems/guess-number-higher-or-lower/&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1709119465537&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Guess Number Higher or Lower - LeetCode&quot; data-og-description=&quot;Can you solve this real interview question? Guess Number Higher or Lower - We are playing the Guess Game. The game is as follows: I pick a number from 1 to n. You have to guess which number I picked. Every time you guess wrong, I will tell you whether the &quot; data-og-host=&quot;leetcode.com&quot; data-og-source-url=&quot;https://leetcode.com/problems/guess-number-higher-or-lower/&quot; data-og-url=&quot;https://leetcode.com/problems/guess-number-higher-or-lower/description&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cETZxL/hyVurfpvpx/nw4ZRLKbFG0sF1NLC0a5L0/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/guess-number-higher-or-lower/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://leetcode.com/problems/guess-number-higher-or-lower/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cETZxL/hyVurfpvpx/nw4ZRLKbFG0sF1NLC0a5L0/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Guess Number Higher or Lower - LeetCode&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Can you solve this real interview question? Guess Number Higher or Lower - We are playing the Guess Game. The game is as follows: I pick a number from 1 to n. You have to guess which number I picked. Every time you guess wrong, I will tell you whether the&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;leetcode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 문제 설명&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1에서 부터 n까지 중 숫자를 하나 pick했을 때, pick한 숫자를 예측하는 Guess Game을 반복한다고 했을 때,&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;pick한 숫자를 반환하는 것.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여기서 사전에 정의된 guess(int num)라는 API를 사용하는데,&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;만약 나의 추측이 실제 pick한 값보다 크면 -1을 반환하고,&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실제 pick한 값보다 작으면 1을 반환하고,&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;만약 pick한 값과 동일하면 0을 반환한다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예시1) 예를 들어 n=10이고 pick=6(이건 parameter로 주어지는게 아니다.)이었을 때, guess함수를 호출하면서, pick이 6이라는 것을 판단한 뒤 6을 반환하는 것.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;3. 처음 풀이&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;LeetCode 367과 너무 비슷해서, 스킵할까 고민했던 문제. (367번 풀이: &lt;a style=&quot;color: #000000;&quot; href=&quot;https://codingbubu.tistory.com/149&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://codingbubu.tistory.com/149&lt;/a&gt;)&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;결국 이것도 그냥 1부터 n까지 for문을 돌리면서, guess(num) == 0일 때를 찾아서 해당 값을 return해도 되겠지만,&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이렇게 하면 time complexity가 높아진다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이전에 풀었던 풀이처럼, binary search를 사용하게 되면, O(logN)만큼의 시간복잡도를 가지게 효율적으로 코드 작성이 가능하다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여기서도 left, right를 1과 n으로 한 pointer를 두고,&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;left &amp;lt;= right일 때까지 while문을 반복하면서,&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(left+right)//2를 num으로 셋팅한 후,&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;만약 guess(num) == 0이면 num을 바로 return하고,&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;guess(num) == -1이 나왔다면, 내가 예측한 숫자가 더 크다는 것이므로, right를 num -1로 이동시킨다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;마찬가지로 guess(num) == 1이 나왔다면, 내가 예측한 숫자가 더 작다는 것이므로, left를 num+1로 이동시킨다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;runtime이 99.74%로 무난하게 통과하였다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709119843874&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# The guess API is already defined for you.
# @param num, your guess
# @return -1 if num is higher than the picked number
#          1 if num is lower than the picked number
#          otherwise return 0
# def guess(num: int) -&amp;gt; int:

class Solution:
    def guessNumber(self, n: int) -&amp;gt; int:
        
        left, right = 1, n 
        
        while left &amp;lt;= right:
            num = (left+right)//2

            if guess(num) == 0:
                return num 
            
            if guess(num) == -1:
                right = num -1 
            
            elif guess(num) == 1:
                left = num +1&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4. 다른 풀이&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;거의 대부분이 binary search를 공식처럼.. 하여 풀고 있어서, 다른 풀이가 거의 없었다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Algorithm/LeetCode</category>
      <category>binary search</category>
      <category>easy</category>
      <category>Guess Number Higher or Lower</category>
      <category>Interactive</category>
      <category>leetcode</category>
      <category>leetcode 374</category>
      <category>리트코드</category>
      <category>리트코드 374</category>
      <category>쉬움</category>
      <category>이진 검색</category>
      <author>펩시_콜라</author>
      <guid isPermaLink="true">https://codingbubu.tistory.com/150</guid>
      <comments>https://codingbubu.tistory.com/150#entry150comment</comments>
      <pubDate>Wed, 27 Mar 2024 19:00:02 +0900</pubDate>
    </item>
    <item>
      <title>LeetCode 139(Word Break, Python)</title>
      <link>https://codingbubu.tistory.com/148</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;1. 문제 링크&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/word-break/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://leetcode.com/problems/word-break/&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1709040895887&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Word Break - LeetCode&quot; data-og-description=&quot;Can you solve this real interview question? Word Break - Given a string s and a dictionary of strings wordDict, return true if s can be segmented into a space-separated sequence of one or more dictionary words. Note that the same word in the dictionary may&quot; data-og-host=&quot;leetcode.com&quot; data-og-source-url=&quot;https://leetcode.com/problems/word-break/&quot; data-og-url=&quot;https://leetcode.com/problems/word-break/description&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/8L8zg/hyVqi5f3vm/CYzb8r1MLKKyQF7J4Q9qPk/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/word-break/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://leetcode.com/problems/word-break/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/8L8zg/hyVqi5f3vm/CYzb8r1MLKKyQF7J4Q9qPk/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Word Break - LeetCode&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Can you solve this real interview question? Word Break - Given a string s and a dictionary of strings wordDict, return true if s can be segmented into a space-separated sequence of one or more dictionary words. Note that the same word in the dictionary may&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;leetcode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;2. 문제 설명&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;문자열과 사전(단어들이 들어 있는 리스트)이 주어졌을 때, 사전의 단어들을 조합하여(반복 가능) 문자열을 만들 수 있는 지 따져 True, False 반환하기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;예시) s = &quot;leetcode&quot;, wordDict = [&quot;leet&quot;, &quot;code&quot;] 이면 &amp;ldquo;leet&amp;rdquo; + &amp;ldquo;code&amp;rdquo;로 가능하여 True&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;3. 처음 풀이&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;예시) s = &quot;applepenapple&quot;, wordDict = [&quot;apple&quot;,&quot;pen&quot;]&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;s의 첫 글자인 a를 start로 고정하고 end를 순회하며 a, ap, app, appl, apple, applep, &amp;hellip;., applepenapple 까지 살펴보며 wordDict에 있는 지 살펴본다. 여기에서 있는 것은 apple 하나이다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;그러면 apple까지는 만들 수 있으므로 이제 p는 start로 조사할 후보(candi)이다. p를 start로 고정하고 end를 순회하면 p, pe, pen, &amp;hellip;, penapple 중 wordDict에 있는 지 살펴 본다. 여기에서 있는 것은 pen 하나이다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;그러면 applepen까지는 만들 수 있으므로 이제 a는 start로 조사할 후보(candi)이다. 마찬가지로 마지막 apple까지 만들 수 있다. 따라서 참.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709041032546&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -&amp;gt; bool:
        # 단어 사전을 집합으으로 변환하여 빠른 검색을 가능하게 함
        wordDict = set(wordDict)
        # 아직 처리하지 않은 부분 문자열의 시작 인덱스를 추적하는 리스트
        candi = [0]
        # 이미 처리한 부분 문자열의 시작 인덱스를 추적하여 중복 처리 방지
        seen = set()
        # 동적 프로그래밍을 위한 2D 배열, 단어 사전을 사용하여 부분 문자열을 나눌 수 있는지 여부 저장
        dp = [[False]*(len(s))] * (len(s))
        
        while candi:
            # 아직 처리하지 않은 부분 문자열의 시작 인덱스를 가져옴
            start = candi.pop(0) 
            if start not in seen:
                seen.add(start)
                # 현재 부분 문자열을 끝까지 순회
                for end in range(start, len(s)):
                    # 현재 부분 문자열이 단어 사전에 있는 단어와 일치하는지 확인
                    if s[start:end + 1] in wordDict:
                        dp[start][end] = True
                        # 다음에 처리할 부분 문자열의 시작 인덱스를 추가
                        if end + 1 not in seen:
                            candi.append(end + 1)

        # 전체 문자열이 단어 사전을 사용하여 나눌 수 있는지 여부를 반환
        return dp[-1][-1]&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;4. 다른 풀이&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;DP를 이용한 풀이, 핵심 아이디어는 비슷하지만 훨씬 깔끔하다. &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709041051976&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -&amp;gt; bool:
                # Convert wordDict into a set for O(1) lookup
        wordSet = set(wordDict)
        
        # Initialize dp list with false values and set the first value to true
        dp = [False] * (len(s)+1)
        dp[0] = True

        # Iterate over the string
        for i in range(1, len(s)+1):
            # For each position, check all possible words that end at this position
            for j in range(i):
                word=s[j:i]
                if dp[j] and word in wordSet:
                    dp[i] = True
                    break

        # Return if the entire string can be segmented or not
        return dp[len(s)]&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;재귀 함수에 메모이제이션을 적용한 풀이&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;startswith 이라는 메서드가 있구나.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709041091115&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -&amp;gt; bool:
        
        def construct(current,wordDict, memo={}):
            if current in memo:
                return memo[current]

            if not current:
                return True

            for word in wordDict:
                if current.startswith(word):
                    new_current = current[len(word):]
                    memo[current] = True
                    if construct(new_current,wordDict,memo):
                        return True

            memo[current] = False
            return False

        return construct(s,wordDict)&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;5. 배운 점&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;처음에 백트래킹으로 시도했다가 타임 리밋 에러에 걸렸다. 이것 저것 최적화를 시도해보았지만 백트래킹으로 해결하지 못하였다. 백트래킹에 몰입하여 DP를 떠올리지 못하였다. DP&amp;hellip; 참 유용하고도 떠올리기 힘든 아이디어..&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;시도했던 백트래킹 풀이가 실패했었는데, 이는 메모이제이션을 적용하지 않았기 때문이다. 마지막 풀이를 보니까 작동 구조는 비슷한데 메모이제이션을 활용하여 빠른 속도를 보여준다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;str.startswith(prefix[, start[, end]])&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;startswith()&lt;/b&gt; 메서드는 문자열이 지정된 접두사로 시작하는지 여부를 검사하는 Python 문자열 메서드&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;prefix&lt;/b&gt;: 검사하려는 접두사 문자열입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;start&lt;/b&gt; (옵션): 검사를 시작할 문자열의 인덱스를 지정합니다. 기본값은 0입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;end&lt;/b&gt; (옵션): 검사를 종료할 문자열의 인덱스를 지정합니다. 기본값은 문자열의 길이입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;startswith()&lt;/b&gt; 메서드는 문자열이 지정된 접두사로 시작하면 **True**를 반환하고, 그렇지 않으면 **False**를 반환합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;text = &quot;Hello, world!&quot;

# &quot;Hello&quot;로 시작하는지 확인
result = text.startswith(&quot;Hello&quot;)
print(result)  # 출력: True

# &quot;world&quot;로 시작하는지 확인 (대소문자 구분)
result = text.startswith(&quot;world&quot;)
print(result)  # 출력: False

# 인덱스 7부터 시작하는 &quot;world&quot;로 시작하는지 확인
result = text.startswith(&quot;world&quot;, 7)
print(result)  # 출력: True&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Algorithm/LeetCode</category>
      <category>back tracking</category>
      <category>DP</category>
      <category>Dynamic</category>
      <category>leetcode 139</category>
      <category>Programming</category>
      <category>recursion</category>
      <category>recursive</category>
      <category>trie</category>
      <category>Word Break</category>
      <category>리트코드 139번</category>
      <author>제로_콜라</author>
      <guid isPermaLink="true">https://codingbubu.tistory.com/148</guid>
      <comments>https://codingbubu.tistory.com/148#entry148comment</comments>
      <pubDate>Tue, 26 Mar 2024 19:00:13 +0900</pubDate>
    </item>
    <item>
      <title>LeetCode 367(Valid Perfect Square, Python)</title>
      <link>https://codingbubu.tistory.com/149</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. 문제 링크&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://leetcode.com/problems/valid-perfect-square/description/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://leetcode.com/problems/valid-perfect-square/description/&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1709117654348&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Valid Perfect Square - LeetCode&quot; data-og-description=&quot;Can you solve this real interview question? Valid Perfect Square - Given a positive integer num, return true if num is a perfect square or false otherwise. A perfect square is an integer that is the square of an integer. In other words, it is the product o&quot; data-og-host=&quot;leetcode.com&quot; data-og-source-url=&quot;https://leetcode.com/problems/valid-perfect-square/description/&quot; data-og-url=&quot;https://leetcode.com/problems/valid-perfect-square/description&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bcO0Uk/hyVqsUBTEi/cBiiMqAFPCuKHOzpkHgYAk/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/valid-perfect-square/description/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://leetcode.com/problems/valid-perfect-square/description/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bcO0Uk/hyVqsUBTEi/cBiiMqAFPCuKHOzpkHgYAk/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Valid Perfect Square - LeetCode&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Can you solve this real interview question? Valid Perfect Square - Given a positive integer num, return true if num is a perfect square or false otherwise. A perfect square is an integer that is the square of an integer. In other words, it is the product o&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;leetcode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 문제 설명&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;양의 정수 num이 주어졌을 때, perfect square면 True를 그렇지 않으면 False를 반환&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여기서 perfect square란, x^2 = num이 되는 정수 x가 존재한다는 것을 의미한다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sqrt같은 built-in library를 사용하진 말것.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. 처음 풀이&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;가장 naive하게는 num보다 작은 i에 대해 for 문을 돌리면서, i^2 == num인지를 check할 수 있지만,&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이렇게 하면 시간복잡도가 올라가고, 실제 leetcode 에서는 time limit이 걸린다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;binary search로, 점점 경우의수를 좁혀나가는 식으로 풀어야겠다고 생각을 했다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이에 left, right라는 pointer를 두고, mid = (left+right)//2로 둔 뒤에,&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;만약 mid를 제곱했을 때 num이 나온다면, True를 반환,&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;만약 mid를 제곱한 것이 num보다 크다면, pointer를 왼쪽으로 이동시킬 필요가 있다.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예를 들어, 아래 그림처럼 mid가 10이어서, mid를 제곱한 100이 num보다 크다면, pointer는 left와 mid 사이로 이동해야 한다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러므로 right를 mid-1로 이동시켜 준뒤 while문을 반복하면, 0~9 사이의 값 중에서 다시 해를 찾는 과정을 반복할 것이다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;반대로 mid를 제곱한 값이 num보다 작다면, pointer가 오른쪽으로 이동이 되어야 하고,&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이때는 반대로 left = mid+1로 바꾸면서 pointer를 이동시키면 되겠다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-02-28 오후 8.06.38.png&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;214&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cw5g4n/btsFisDRFDF/DK0N0SUQRK3StPGgp0cgEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cw5g4n/btsFisDRFDF/DK0N0SUQRK3StPGgp0cgEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cw5g4n/btsFisDRFDF/DK0N0SUQRK3StPGgp0cgEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcw5g4n%2FbtsFisDRFDF%2FDK0N0SUQRK3StPGgp0cgEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;496&quot; height=&quot;139&quot; data-filename=&quot;스크린샷 2024-02-28 오후 8.06.38.png&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;214&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;해당 과정을 left &amp;lt;= right인 상황에서 계속 반복하고, 이 때 while문 안에서 True가 반환되거나,&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;반환되지 않고 While문을 빠져나오면 False를 반환하게 된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709118602981&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution:
    def isPerfectSquare(self, num: int) -&amp;gt; bool:
        left, right = 0, num
 
        while left &amp;lt;= right:
            
            mid = (left+right)//2

            if mid ** 2 == num:
                return True
            
            if mid ** 2 &amp;lt; num:
                left = mid+1
            
            if mid ** 2 &amp;gt; num:
                right = mid-1
        
        return False&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4. 다른 풀이&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;출제자의 의도를 벗어난 야매 풀이긴 하지만 (sqrt를 쓰지 말랬으므로), 아래처럼 푼 풀이도 있었다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709118654186&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution:
    def isPerfectSquare(self, num: int) -&amp;gt; bool:
        return float(num ** 0.5).is_integer()&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 대부분의 풀이는 binary search를 사용해서, 위의 처음 풀이와 크게 벗어나는 풀이는 없었다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Algorithm/LeetCode</category>
      <category>binary search</category>
      <category>easy</category>
      <category>Leet Code 367</category>
      <category>leetcode</category>
      <category>math</category>
      <category>Valid Perfect Square</category>
      <category>리트코드</category>
      <category>리트코드 367</category>
      <category>이진 검색</category>
      <category>이진 서치</category>
      <author>펩시_콜라</author>
      <guid isPermaLink="true">https://codingbubu.tistory.com/149</guid>
      <comments>https://codingbubu.tistory.com/149#entry149comment</comments>
      <pubDate>Mon, 25 Mar 2024 19:00:02 +0900</pubDate>
    </item>
    <item>
      <title>LeetCode 138(Copy List with Random Pointer, Python)</title>
      <link>https://codingbubu.tistory.com/147</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;1. 문제 링크&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/copy-list-with-random-pointer/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://leetcode.com/problems/copy-list-with-random-pointer/&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1708909846629&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Copy List with Random Pointer - LeetCode&quot; data-og-description=&quot;Can you solve this real interview question? Copy List with Random Pointer - A linked list of length n is given such that each node contains an additional random pointer, which could point to any node in the list, or null. Construct a deep copy [https://en.&quot; data-og-host=&quot;leetcode.com&quot; data-og-source-url=&quot;https://leetcode.com/problems/copy-list-with-random-pointer/&quot; data-og-url=&quot;https://leetcode.com/problems/copy-list-with-random-pointer/description&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/biVlKe/hyVqrtJGfG/TTQgXQpudTKjMff1B82BBK/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/copy-list-with-random-pointer/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://leetcode.com/problems/copy-list-with-random-pointer/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/biVlKe/hyVqrtJGfG/TTQgXQpudTKjMff1B82BBK/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Copy List with Random Pointer - LeetCode&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Can you solve this real interview question? Copy List with Random Pointer - A linked list of length n is given such that each node contains an additional random pointer, which could point to any node in the list, or null. Construct a deep copy [https://en.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;leetcode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;2. 문제 설명&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;연결 리스트가 주어지는데 다음 노드를 가르키는 .next 속성 뿐 아니라 연결 리스트 중 임의의 노드를 가르키는 .random 속성도 가지고 있음.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;연결 리스트의 head만 주어졌을 때 이와 똑같은 값과 연결 관계를 가진 연결 리스트를 deep copy하여 head를 반환하기.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;이때, 주어진 연결 리스트의 노드 자체를 참고하면 안된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;3. 처음 풀이&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;주어진 리스트를 한 번 순회하며 .val, .next 정보를 복사한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;주어진 연결 리스트와 새로 만든 연결 리스트를 처음부터 순회하며, .random 정보를 연결한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;이때, 두 리스트에 cur 를 하나 정해두고 random을 head에서부터 한 칸씩 이동하여 cur.random과 같아질 때 까지 이동한다. 같아지면 새로 만든 연결 리스트에서 cur.random을 연결해주고 cur를 하나 이동 시킨다. 이를 반복. n&amp;sup2;의 시간 복잡도.&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1708909867882&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;&quot;&quot;
# Definition for a Node.
class Node:
    def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
        self.val = int(x)
        self.next = next
        self.random = random
&quot;&quot;&quot;

class Solution:
    def copyRandomList(self, head: 'Optional[Node]') -&amp;gt; 'Optional[Node]':
        if not head:
            return None
            
        head_copy = Node(head.val)
        cur_copy = head_copy
        cur_origin = head
        cur_origin = cur_origin.next

        while cur_origin: # .val 과 .next를 복사한다. 
            cur_copy.next = Node(cur_origin.val)
            cur_copy = cur_copy.next
            cur_origin = cur_origin.next

        cur_copy = head_copy
        random_copy = head_copy
        cur_origin = head
        random_origin = head 

        while cur_copy: # .random 을 복사하는 과정. cur_copy, cur_origin은 동시에 한 칸씩 이동
            while random_origin != cur_origin.random: # random_origin을 head에서 출발시켜 cur_origin.random 과 같을 때까지 이동
                random_copy = random_copy.next
                random_origin = random_origin.next
            cur_copy.random = random_copy # cur_copy.random 연결
            cur_copy = cur_copy.next # cur_copy 한 칸 이동
            cur_origin = cur_origin.next # cur_origin 한 칸 이동
            random_copy = head_copy # random_copy를 head_copy로 초기화
            random_origin = head # random_origin을 head로 초기화
        
        return head_copy&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;4. 다른 풀이&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;해쉬맵 이용하는 풀이. 처음에 비슷한 시도를 하였으나 dict.get 메소드를 몰라서 key error가 나서 처리하는 도중 풀이 방향을 바꾸었다. dict[key]의 경우 key가 없으면 에러가 나지만 dict.get(key)는 key가 없으면 None 반환.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;수학에서 isomorphism 함수와 비슷한 느낌이다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;시간 복잡도 O(n), 공간 복잡도 O(n)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1708909886254&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution:
    def copyRandomList(self, head: 'Optional[Node]') -&amp;gt; 'Optional[Node]':
        if not head:
            return None

        mapping = {}  # 원본 노드와 복사된 노드의 매핑을 저장할 딕셔너리

        # 복사한 노드의 리스트 생성 및 매핑
        cur_origin = head
        while cur_origin:
            mapping[cur_origin] = Node(cur_origin.val)
            cur_origin = cur_origin.next

        # 복사한 노드의 next와 random 포인터 설정
        cur_origin = head
        while cur_origin:
            mapping[cur_origin].next = mapping.get(cur_origin.next)
            mapping[cur_origin].random = mapping.get(cur_origin.random)
            cur_origin = cur_origin.next

        return mapping[head]&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;Interweaving 기법&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;1&amp;rarr;2&amp;rarr;3&amp;rarr;4 가 주어졌을 때&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;1&amp;rarr;1'&amp;rarr;2&amp;rarr;2'&amp;rarr;3&amp;rarr;3'&amp;rarr;4&amp;rarr;4' 로 만들고 .random을 연결한 후&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;1&amp;rarr;2&amp;rarr;3&amp;rarr;4, 1'&amp;rarr;2'&amp;rarr;3'&amp;rarr;4'로 다시 쪼개는 풀이&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;시간 복잡도 O(n), 공간 복잡도 O(1)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1708909908413&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution:
    def copyRandomList(self, head: 'Optional[Node]') -&amp;gt; 'Optional[Node]':
        if not head:
            return None
        
        curr = head
        while curr: # 1&amp;rarr;2&amp;rarr;3&amp;rarr;4 가 주어졌을 때 1&amp;rarr;1'&amp;rarr;2&amp;rarr;2'&amp;rarr;3&amp;rarr;3'&amp;rarr;4&amp;rarr;4' 로 만드는 과정
            new_node = Node(curr.val, curr.next)
            curr.next = new_node
            curr = new_node.next
            
        curr = head
        while curr: # 1'의 random은 1의 random의 next임. 이를 이용하여 random 연결.
            if curr.random:
                curr.next.random = curr.random.next
            curr = curr.next.next
        
        old_head = head
        new_head = head.next
        curr_old = old_head
        curr_new = new_head
        
        while curr_old: # 섞여있는 old, new를 다시 두칸씩 건너며 풀어주는 작업.
            curr_old.next = curr_old.next.next
            curr_new.next = curr_new.next.next if curr_new.next else None
            curr_old = curr_old.next
            curr_new = curr_new.next
            
        return new_head&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;5. 배운 점&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;dict.get(key)는 딕셔너리 key가 없을 경우 None을 반환한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;Interweaving 기법이 꽤 강력하고 자주 쓰일 듯하다. 마치 지퍼를 지그재그 짜맞추고 풀어주는 느낌, 바느질을 하는 느낌이다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Algorithm/LeetCode</category>
      <category>.next</category>
      <category>.random</category>
      <category>dict</category>
      <category>Get</category>
      <category>Hash Map</category>
      <category>hash table</category>
      <category>interweaving</category>
      <category>linked</category>
      <category>list</category>
      <author>제로_콜라</author>
      <guid isPermaLink="true">https://codingbubu.tistory.com/147</guid>
      <comments>https://codingbubu.tistory.com/147#entry147comment</comments>
      <pubDate>Sun, 24 Mar 2024 19:00:21 +0900</pubDate>
    </item>
    <item>
      <title>LeetCode 350(Intersection of Two Arrays II, Python)</title>
      <link>https://codingbubu.tistory.com/136</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 문제 링크&amp;nbsp;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://leetcode.com/problems/intersection-of-two-arrays-ii/description/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://leetcode.com/problems/intersection-of-two-arrays-ii/description/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1708751044126&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Intersection of Two Arrays II - LeetCode&quot; data-og-description=&quot;Can you solve this real interview question? Intersection of Two Arrays II - Given two integer arrays nums1 and nums2, return an array of their intersection. Each element in the result must appear as many times as it shows in both arrays and you may return &quot; data-og-host=&quot;leetcode.com&quot; data-og-source-url=&quot;https://leetcode.com/problems/intersection-of-two-arrays-ii/description/&quot; data-og-url=&quot;https://leetcode.com/problems/intersection-of-two-arrays-ii/description&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/MX5A2/hyVmPJrGoR/e5WISKErziV7k5BqQfoWN1/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/intersection-of-two-arrays-ii/description/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://leetcode.com/problems/intersection-of-two-arrays-ii/description/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/MX5A2/hyVmPJrGoR/e5WISKErziV7k5BqQfoWN1/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Intersection of Two Arrays II - LeetCode&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Can you solve this real interview question? Intersection of Two Arrays II - Given two integer arrays nums1 and nums2, return an array of their intersection. Each element in the result must appear as many times as it shows in both arrays and you may return&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;leetcode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 문제 설명&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정수로 구성된 array nums1과 nums2가 있을 때, 그 둘의 intersaction을 찾아 array형태로 반환.&lt;/li&gt;
&lt;li&gt;한 정수가  두 array에 여러번씩 등장할 수 있고, 그러면 최소로 등장한 횟수만큼 array에 반환해야 한다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;예시1)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;nums1 = [1,2,2,1], nums2 = [2,2]이면, 2가 2번 교집합이 생겼으므로, [2,2]를 반환&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;예시2)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;nums1 = [4,9,5], nums2 = [4,9]이면, 4와 9가 교집합이고 각 1번씩 등장하였으므로, [4,9]를 반환
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여기서 반환하는 순서는 상관이 없어서, [9,4]를 반환해도 무방하다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 처음 풀이&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;아주 처음에는 직전 문제인 Intersection of Two Arrays와 비슷하게 접근하려고&lt;/li&gt;
&lt;li&gt;우선 중복 포함되지 않은 교집합을 구한 뒤,
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 교집합을 for문을 돌리면서,&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 element가 각 nums1, nums2에 몇번 등장했는지를 계산 후, 최소 등장만큼 result에 추가해주는 방식으로 코드를 작성하였다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;runtime이 50% 정도로 좋게 나오진 않았는데,
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;nums1, nums2에서 i를 찾아 count하는 연산, min으로 두 count의 최솟값을 구하는 연산이 포함되어있어서이지 않을까 싶었다. (두개처럼 하지 않고 푸는 방법도 있을테니)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1708751450400&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -&amp;gt; List[int]:

        intersect =  set(nums1)  &amp;amp; set(nums2)
        result = []

        for i in intersect:
            count = min(nums1.count(i), nums2.count(i))
            result += [i]*count
        
        return result&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 다른 풀이&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;속도 측면에서 개선된 풀이&lt;/li&gt;
&lt;li&gt;nums1에 대해서 i 별 개수를 세는 dictionary를 만들어 두고, (nums1_dict)&lt;/li&gt;
&lt;li&gt;nums2의 element i에 대해 for문을 돌리면서,
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;i가 nums1_dict에 존재하면, result array에 append하고,&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여기서 nums1_dict.get(i)를 써서, 만약 값이 0이면 false가 되므로, 1이상일 때 result.append가 돌 수 있도록 하였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;그 만큼 nums1_dict에서 줄여주어야하니, nums1_dict[i]의 값을 1씩 제거하는 식으로 코드를 작성하였다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;runtime 99%로 속도 측면에서 개선된 풀이&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1708751593966&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -&amp;gt; List[int]:
        result = []
        nums1_dict = {}

        for i in nums1:
            if i in nums1_dict:
                nums1_dict[i] +=1
            else:
                nums1_dict[i] =1
        
        for i in nums2:
            if nums1_dict.get(i):
                result.append(i)
                nums1_dict[i] -=1
        
        return result&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;아래는 다른 사람의 풀이로, sort를 활용한 경우도 있었다.&lt;/li&gt;
&lt;li&gt;각 nums1, nums2를 sort로 오름차순 정렬을 하고,&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;while문을 사용하여, i, j 두개의 pointer를 이동시키는데,
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;두 값이 같으면 result에 append하고&lt;/li&gt;
&lt;li&gt;만약 nums1의 값이 크면 j를 한칸 오른쪽으로 이동시키고,&lt;/li&gt;
&lt;li&gt;반대의 경우에는 i를 한칸 오른쪽으로 이동시키면서 pointer를 이동한다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이것도 runtime 90% 정도로 잘 나온다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1708751901642&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -&amp;gt; List[int]:
        nums1.sort()
        nums2.sort()
        
        i, j = 0, 0
        ret = []
        while i &amp;lt; len(nums1) or j &amp;lt; len(nums2):
            if i == len(nums1) or j == len(nums2):
                break
            elif nums1[i] == nums2[j]:
                ret.append(nums1[i])
                i += 1
                j += 1
            elif nums1[i] &amp;gt; nums2[j]:
                j += 1
            else:
                i += 1
        
        return ret&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Algorithm/LeetCode</category>
      <category>Array</category>
      <category>hash table</category>
      <category>Intersection of Two Arrays II</category>
      <category>leetcode</category>
      <category>leetcode 350</category>
      <category>sort</category>
      <category>sorting</category>
      <category>Two Pointer</category>
      <category>리트코드</category>
      <category>리트코드 350</category>
      <author>펩시_콜라</author>
      <guid isPermaLink="true">https://codingbubu.tistory.com/136</guid>
      <comments>https://codingbubu.tistory.com/136#entry136comment</comments>
      <pubDate>Sat, 23 Mar 2024 19:00:42 +0900</pubDate>
    </item>
    <item>
      <title>LeetCode 349(Intersection of Two Arrays, Python)</title>
      <link>https://codingbubu.tistory.com/157</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;1. 문제 링크&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/intersection-of-two-arrays/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://leetcode.com/problems/intersection-of-two-arrays/&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1709377631042&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Intersection of Two Arrays - LeetCode&quot; data-og-description=&quot;Can you solve this real interview question? Intersection of Two Arrays - Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.&quot; data-og-host=&quot;leetcode.com&quot; data-og-source-url=&quot;https://leetcode.com/problems/intersection-of-two-arrays/&quot; data-og-url=&quot;https://leetcode.com/problems/intersection-of-two-arrays/description&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/qeopQ/hyVqwiWar9/xRGR1gFfXLN4vITTIZwhdk/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/intersection-of-two-arrays/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://leetcode.com/problems/intersection-of-two-arrays/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/qeopQ/hyVqwiWar9/xRGR1gFfXLN4vITTIZwhdk/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Intersection of Two Arrays - LeetCode&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Can you solve this real interview question? Intersection of Two Arrays - Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;leetcode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;2. 문제 설명&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;두 개의 리스트가 주어졌을 때 중복된 요소를 담은 리스트를 반환하는 문제. 이때 반환하는 리스트에는 각 요소가 유니크해야함. 두 번 이상 나오면 안됨.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;3. 처음 풀이&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;각 리스트를 집합으로 바꾸어 중복을 제거 후 두 집합을 교집합 연산 후 리스트로 바꾸어 반환&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;sas&quot;&gt;&lt;code&gt;class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -&amp;gt; List[int]:
        return list(set(nums1) &amp;amp; set(nums2))
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;4. 다른 풀이&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;직접 첫번째 리스트를 순회하며 그 값이 두번째 리스트에 있고 아직 결과에 추가하지 않았다면 추가하기&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;haskell&quot;&gt;&lt;code&gt;class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -&amp;gt; List[int]:
        r=[]
        for i in range(len(nums1)):
            if (nums1[i] in nums2 and nums1[i] not in r):
                r.append(nums1[i])
        return (r)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;5. 배운 점&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;간단한 문제이다. 그럼에도 배운 점이라고 하면 두 집합 A, B의 교집합을 구할때&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;나는 A&amp;amp;B를 하였고&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;또 다른 방법으로는 A-(A-B), A.intersection(B), set.intersection(A, B) 가 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Algorithm/LeetCode</category>
      <category>349번</category>
      <category>Intersection</category>
      <category>leetcode 349</category>
      <category>set</category>
      <category>교집합</category>
      <category>리트코드</category>
      <category>집합</category>
      <author>제로_콜라</author>
      <guid isPermaLink="true">https://codingbubu.tistory.com/157</guid>
      <comments>https://codingbubu.tistory.com/157#entry157comment</comments>
      <pubDate>Fri, 22 Mar 2024 19:00:38 +0900</pubDate>
    </item>
  </channel>
</rss>