diff --git a/longest-substring-without-repeating-characters/socow.py b/longest-substring-without-repeating-characters/socow.py new file mode 100644 index 0000000000..91baa03a38 --- /dev/null +++ b/longest-substring-without-repeating-characters/socow.py @@ -0,0 +1,55 @@ +""" +๐Ÿ“š 3. Longest Substring Without Repeating Characters + +๐Ÿ“Œ ๋ฌธ์ œ ์š”์•ฝ +- ์ฃผ์–ด์ง„ ๋ฌธ์ž์—ด s์—์„œ ์ค‘๋ณต ๋ฌธ์ž๊ฐ€ ์—†๋Š” ๊ฐ€์žฅ ๊ธด ๋ถ€๋ถ„ ๋ฌธ์ž์—ด์˜ ๊ธธ์ด ์ฐพ๊ธฐ +- ์˜ˆ: "abcabcbb" โ†’ "abc" โ†’ 3 + +๐ŸŽฏ ํ•ต์‹ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ +- ํŒจํ„ด: ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ (Sliding Window) + ํ•ด์‹œ๋งต +- ์‹œ๊ฐ„๋ณต์žก๋„: O(n) +- ๊ณต๊ฐ„๋ณต์žก๋„: O(min(n, m)) - m์€ ๋ฌธ์ž ์ง‘ํ•ฉ ํฌ๊ธฐ + +๐Ÿ’ก ํ•ต์‹ฌ ์•„์ด๋””์–ด +1. left, right ๋‘ ํฌ์ธํ„ฐ๋กœ ์œˆ๋„์šฐ ๊ด€๋ฆฌ +2. ํ•ด์‹œ๋งต์— ๊ฐ ๋ฌธ์ž์˜ ๋งˆ์ง€๋ง‰ ์œ„์น˜ ์ €์žฅ +3. ์ค‘๋ณต ๋ฐœ๊ฒฌ ์‹œ โ†’ left๋ฅผ ์ค‘๋ณต ๋ฌธ์ž ๋‹ค์Œ์œผ๋กœ ์ ํ”„! +4. ๋งค ๋‹จ๊ณ„๋งˆ๋‹ค ์œˆ๋„์šฐ ํฌ๊ธฐ(right - left + 1) ์ตœ๋Œ“๊ฐ’ ๊ฐฑ์‹  +""" + + +class Solution: + def lengthOfLongestSubstring(self, s: str) -> int: + char_index = {} # ๋ฌธ์ž โ†’ ๋งˆ์ง€๋ง‰ ์ธ๋ฑ์Šค + left = 0 + max_len = 0 + + for right, char in enumerate(s): + # ์ค‘๋ณต ๋ฌธ์ž๊ฐ€ ํ˜„์žฌ ์œˆ๋„์šฐ ์•ˆ์— ์žˆ์œผ๋ฉด + if char in char_index and char_index[char] >= left: + left = char_index[char] + 1 # ์ค‘๋ณต ๋‹ค์Œ์œผ๋กœ ์ ํ”„ + + char_index[char] = right # ํ˜„์žฌ ์œ„์น˜ ๊ฐฑ์‹  + max_len = max(max_len, right - left + 1) + + return max_len + + +# Set์„ ์‚ฌ์šฉํ•œ ๋ฐฉ์‹ (๋” ์ง๊ด€์ ) +class SolutionWithSet: + def lengthOfLongestSubstring(self, s: str) -> int: + char_set = set() + left = 0 + max_len = 0 + + for right in range(len(s)): + # ์ค‘๋ณต์ด ์‚ฌ๋ผ์งˆ ๋•Œ๊นŒ์ง€ left ์ด๋™ + while s[right] in char_set: + char_set.remove(s[left]) + left += 1 + + char_set.add(s[right]) + max_len = max(max_len, right - left + 1) + + return max_len + diff --git a/reverse-linked-list/socow.py b/reverse-linked-list/socow.py new file mode 100644 index 0000000000..5773c0976b --- /dev/null +++ b/reverse-linked-list/socow.py @@ -0,0 +1,41 @@ +""" +๐Ÿ“š 206. Reverse Linked List + +๐Ÿ“Œ ๋ฌธ์ œ ์š”์•ฝ +- ๋‹จ๋ฐฉํ–ฅ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ, ๋ฆฌ์ŠคํŠธ๋ฅผ ๋’ค์ง‘์–ด์„œ ๋ฐ˜ํ™˜ํ•˜๊ธฐ +- ์˜ˆ: 1โ†’2โ†’3โ†’4โ†’5 โ†’ 5โ†’4โ†’3โ†’2โ†’1 + +๐ŸŽฏ ํ•ต์‹ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ +- ํŒจํ„ด: ๋ฐ˜๋ณต (Iterative) +- ์‹œ๊ฐ„๋ณต์žก๋„: O(n) +- ๊ณต๊ฐ„๋ณต์žก๋„: O(1) (๋ฐ˜๋ณต) + +๐Ÿ’ก ํ•ต์‹ฌ ์•„์ด๋””์–ด +1. prev = None, curr = head๋กœ ์‹œ์ž‘ +2. ๊ฐ ๋…ธ๋“œ์—์„œ next๋ฅผ ์ €์žฅ โ†’ curr.next๋ฅผ prev๋กœ ๋ณ€๊ฒฝ +3. prev = curr, curr = next๋กœ ์ด๋™ +4. curr์ด None์ด ๋˜๋ฉด prev๊ฐ€ ์ƒˆ๋กœ์šด head! +""" + +from typing import Optional + + +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + + +# ๋ฐ˜๋ณต ๋ฐฉ์‹ (Iterative) +class Solution: + def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: + prev = None + curr = head + + while curr: + next_node = curr.next # ๋‹ค์Œ ๋…ธ๋“œ ์ €์žฅ + curr.next = prev # ๋ฐฉํ–ฅ ๋’ค์ง‘๊ธฐ + prev = curr # prev ์ด๋™ + curr = next_node # curr ์ด๋™ + + return prev