Skip to content

BitnaKeum/python-algorithm-tests

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

100 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

์‹œ๊ฐ„๋ณต์žก๋„

  • ์‹œ๊ฐ„์ œํ•œ 1์ดˆ๋‹น ์•ฝ 2์ฒœ๋งŒ๋ฒˆ~1์–ต๋ฒˆ ์—ฐ์‚ฐ

  • O(1)

    • List์—์„œ pop()
    • deque์—์„œ pop()/popleft()/append()/appendleft()
    • PriorityQueue์—์„œ get()
    • Dictionary(ํ•ด์‹œ ํ…Œ์ด๋ธ”)์—์„œ in/del ์—ฐ์‚ฐ
    • Set์—์„œ in/del ์—ฐ์‚ฐ
  • O(logn)

    • PriorityQueue์—์„œ put()
    • heapq์—์„œ heappush()/heappop()
    • ์ด์ง„ ํƒ์ƒ‰(Binary Search)
  • O(n)

    • List์—์„œ in ์—ฐ์‚ฐ
    • List์—์„œ pop(n)
    • ํˆฌ ํฌ์ธํ„ฐ
  • O(nlogn)

    • sort(), sorted()
    • ๋ณ‘ํ•ฉ ์ •๋ ฌ, ํ€ต ์ •๋ ฌ
  • O(n^2)

    • ๋ฒ„๋ธ” ์ •๋ ฌ
  • O(2^n)

  • O(n!)


์ž…๋ ฅ ๋ฐ›๊ธฐ
  • ์ •์ˆ˜ 1๊ฐœ
    num = int(input())

  • ์ •์ˆ˜ 2๊ฐœ ์ด์ƒ
    num1, num2 = map(int, input().split())

  • ์‹ฌํ™” ๋ฒ„์ „

    lis = list(map(int, input().split()))  
    # 1 2 3 4 5 -> [1, 2, 3, 4, 5]
    lis = list(map(int, input()))
    # 12345 -> [1, 2, 3, 4, 5]
    lis = input().split()  
    # a b c d e -> ['a', 'b', 'c', 'd', 'e']
    lis = []
    for _ in range(row):  # ํ–‰ ์ˆ˜
      lis.append(list(map(int, input().split())))
    # 1 2 3
    # 4 5 6
    # ->
    # [[1, 2, 3], [4, 5, 6]]
  • ํšจ์œจ์ ์œผ๋กœ ์ž…๋ ฅ ๋ฐ›๊ธฐ

    # ์—ฌ๋Ÿฌ ์ค„์„ ๋ฐ˜๋ณตํ•ด์„œ ์ž…๋ ฅ๋ฐ›์•„์•ผํ•  ๋•Œ, input()์„ ์‚ฌ์šฉํ•˜๋ฉด ์‹œ๊ฐ„์ดˆ๊ณผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ sys.stdin.readline()๋ฅผ ์‚ฌ์šฉ
    import sys
    data = sys.stdin.readline().rstrip()  # rstrip()์€ ๊ฐœํ–‰๋ฌธ์ž๋ฅผ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•จ
    import sys
    input = sys.stdin.readline
    data = input()
  • +ํšจ์œจ์ ์œผ๋กœ ์ถœ๋ ฅํ•˜๊ธฐ

    • ์ฃผ์˜) print() ์•ˆ์— ์ •์ˆ˜๋ฅผ ๋„ฃ์œผ๋ฉด TypeError๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ str()๋กœ ํ˜•๋ณ€ํ™˜ ํ•ด์ค˜์•ผํ•จ
    import sys
    print = sys.stdout.write
    print('๋‚ด์šฉ')

Python ๊ธฐ๋ณธ ๋ฌธ๋ฒ•
  • ์ž์ฃผ ์“ฐ๋Š” ํ•จ์ˆ˜
    • ๋ฆฌ์ŠคํŠธ.insert(idx, value)

    • ์žฌ๊ท€ํ•จ์ˆ˜์˜ ์ตœ๋Œ€ ํ˜ธ์ถœ ํšŸ์ˆ˜ ์ œํ•œ ๋Š˜๋ฆฌ๊ธฐ (default: 3000)

      import sys
      sys.setrecursionlimit(10000)
    • ๋ฌธ์ž์—ด์˜ ํŠน์ • ์ธ๋ฑ์Šค์—์„œ๋ถ€ํ„ฐ ์ฐพ๊ธฐ

      • ๊ฒ€์ƒ‰์€ ํŠน์ • ์ธ๋ฑ์Šค์—์„œ๋ถ€ํ„ฐ ํ•˜์ง€๋งŒ, ๋ฐ˜ํ™˜ ๊ฐ’์€ ์›๋ณธ ๋ฌธ์ž์—ด์—์„œ์˜ ์ธ๋ฑ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค!
      • ๋ฆฌ์ŠคํŠธ์—๋Š” ์ด ๊ธฐ๋Šฅ์ด ์—†์Œ
      s = 'abcba'
      
      s.find('a')     # 0 ('abcba'์˜ ์•ž์—์„œ๋ถ€ํ„ฐ ๊ฒ€์ƒ‰)
      s.find('a', 1)  # 4 ('bcba'์˜ ์•ž์—์„œ๋ถ€ํ„ฐ ๊ฒ€์ƒ‰)
      s.rfind('a')    # 4 ('abcba'์˜ ๋’ค์—์„œ๋ถ€ํ„ฐ ๊ฒ€์ƒ‰)
      s.rfind('a', 1) # 4 ('bcba'์˜ ๋’ค์—์„œ๋ถ€ํ„ฐ ๊ฒ€์ƒ‰)

  • ์ง„๋ฒ• ๋ณ€ํ™˜ํ•˜๊ธฐ

    • n์ง„๋ฒ• โ†’ 10์ง„๋ฒ• ๋ณ€ํ™˜: int(์ˆ˜ ๋ฌธ์ž์—ด, n)

      print(int('1000', 2))   # 8
    • 10์ง„๋ฒ• โ†’ 2์ง„๋ฒ• ๋ณ€ํ™˜: bin()

      num = 8
      print(bin(num))      # '0b1000'
      print(bin(num)[2:])  # '1000

  • Set ์ž๋ฃŒํ˜•

    • ๋นˆ Set ์ƒ์„ฑ: S = set()
      • ์ฃผ์˜) S = {}๋กœ ์“ฐ๋ฉด Dictionary ์ž๋ฃŒํ˜•์œผ๋กœ ์ธ์‹ํ•จ
    • ์ฑ„์›Œ์ง„ Set ์ƒ์„ฑ: S = {1,2,3}
    • ์›์†Œ ์ถ”๊ฐ€: S.add()
      • ์ค‘๋ณต๋œ ์›์†Œ๊ฐ€ ๋“ค์–ด์˜ค๋ฉด ์ค‘๋ณต ์ œ๊ฑฐํ•จ
      • ์ˆœ์„œ๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์ˆœ์„œ๊ฐ€ ์œ ์ง€๋˜์ง€ ์•Š์Œ
    • ์›์†Œ ์ œ๊ฑฐ: S.remove()
      • ํ•ด๋‹น ์›์†Œ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด Error ๋ฐœ์ƒ
      • Error ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ฒŒ ์ œ๊ฑฐํ•˜๋ ค๋ฉด S.discard() ์‚ฌ์šฉ
    • in ์—ฐ์‚ฐ ๊ฐ€๋Šฅ (์‹œ๊ฐ„๋ณต์žก๋„: O(1))
    • ์ง‘ํ•ฉ ์—ฐ์‚ฐ
      • ํ•ฉ์ง‘ํ•ฉ: S1 | S2
      • ๊ต์ง‘ํ•ฉ: S1 & S2
      • ์ฐจ์ง‘ํ•ฉ: S1 - S2
        • ๋” ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•: S1.difference_update(S2)

  • Slicing
    • ๋ฆฌ์ŠคํŠธ ์Šฌ๋ผ์ด์‹ฑ ๊ฒฐ๊ณผ ๊ฐ’์€ ๋ฆฌ์ŠคํŠธํ˜•
    • ์‹ค์ œ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋„ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ!
      lis = [2,4,6,8]
      lis[3:10]  # [8]

  • List Comprehension

    • ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•
      arr = [1,2,3,4,5]
      result = [x for x in arr]  # [1,2,3,4,5]
    • if๋ฌธ ์‚ฌ์šฉ
      arr = [1,2,3,4,5]
      result = [x for x in arr if x < 3]  # [1,2]
    • if ~ else๋ฌธ ์‚ฌ์šฉ
      arr = [5,3,2,7,1]
      result = ['small' if x < 3 else 'big' for x in arr]  # ['big', 'big', 'small', 'big', 'small']

  • ๋ฆฌ์ŠคํŠธ โ†’ ๋ฌธ์ž์—ด

    : ๋ฌธ์ž์—ด์ด ๋“ค์–ด ์žˆ๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ํ•˜๋‚˜์˜ ๋ฌธ์ž์—ด๋กœ ํ•ฉ์น˜๊ธฐ

    ''.join(๋ฆฌ์ŠคํŠธ)


  • ์ •๋ ฌ (Sorting)

    • ๋ฆฌ์ŠคํŠธ ์ •๋ ฌ

      ๋ฆฌ์ŠคํŠธ.sort() : ์›๋ž˜ ๊ฒƒ ๋ฐ”๋€œ
      sorted(๋ฆฌ์ŠคํŠธ) : ์›๋ž˜ ๊ฒƒ ๋ฐ”๋€Œ์ง€ ์•Š์Œ

      • ์˜ˆ์‹œ1

        lis = ["5e", "3a", "1a"]์ผ ๋•Œ,

        1. ํ‘œํ˜„์‹ 1๊ฐœ: ์ฃผ์–ด์ง„ ํ‘œํ˜„์‹์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌ

          • ์ฃผ์–ด์ง„ ํ‘œํ˜„์‹์ด ๋™์ผํ•œ ๊ฐ’๋“ค๋ผ๋ฆฌ๋Š” ๊ธฐ์กด ์ˆœ์„œ ์œ ์ง€

          sorted(lis, key=lambda x: x[1]) # ['3a', '1a', '5e']

        2. ํ‘œํ˜„์‹ 2๊ฐœ: ์ฒซ ๋ฒˆ์งธ ํ‘œํ˜„์‹์„ ์šฐ์„ ์œผ๋กœ ํ•˜๊ณ , ์ฒซ ๋ฒˆ์งธ ํ‘œํ˜„์‹์ด ๊ฐ™์„ ๊ฒฝ์šฐ ๋‘ ๋ฒˆ์งธ ํ‘œํ˜„์‹์— ๋”ฐ๋ผ ์ •๋ ฌ
          sorted(lis, key=lambda x: (x[1], x[0])) # ['1a', '3a', '5e']

      • ์˜ˆ์‹œ2

        lis = ['eee', 'c', 'dd', 'bb', 'aaa']์ผ ๋•Œ,

        • sorted(lis, key=lambda x: len(x))
          sorted(lis, key=len) # ['c', 'dd', 'bb', 'eee', 'aaa']
        • sorted(lis, key=lambda x: (len(x), x)) # ['c', 'bb', 'dd', 'aaa', 'eee']
        • sorted(lis, key=lambda x: (-len(x), x)) # ['aaa', 'eee', 'bb', 'dd', 'c']
          • ์ˆซ์ž ํƒ€์ž…์— ๋Œ€ํ•ด์„œ๋Š” -๋ฅผ ๋ถ™์—ฌ์„œ ๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌ์„ ํ•  ์ˆ˜ ์žˆ์Œ!



    • ๋”•์…”๋„ˆ๋ฆฌ ์ •๋ ฌ

      sorted(๋”•์…”๋„ˆ๋ฆฌ) : ์›๋ž˜ ๊ฒƒ ๋ฐ”๋€Œ์ง€ ์•Š์Œ

      • ์˜ˆ์‹œ

        d = {'b': 3, 'c': 1, 'a': 2}์ผ ๋•Œ,

        • sorted(d)
          sorted(d.keys()) # ['a', 'b', 'c']
        • sorted(d.items())
          sorted(d.items(), key=lambda x: x[0]) # [('a', 2), ('b', 3), ('c', 1)]
        • sorted(d.values()) # [1, 2, 3]
        • sorted(d.items(), key=lambda x: x[1]) # [('c', 1), ('a', 2), ('b', 3)]
        • sorted(d.items(), key=lambda x: (x[0], x[1])) # [('a', 2), ('b', 3), ('c', 1)]

    • ๋ฌธ์ž์—ด ์ •๋ ฌ

      sorted(๋ฌธ์ž์—ด) : ์›๋ž˜ ๊ฒƒ ๋ฐ”๋€Œ์ง€ ์•Š์Œ

      • ์˜ˆ์‹œ: sorted('zebra') # ['a', 'b', 'e', 'r', 'z']

  • ๋ฌธ์ž์—ด์ด ์•ŒํŒŒ๋ฒณ/์ˆซ์ž์ธ์ง€ ํ™•์ธ

    • ์ˆซ์ž๋กœ๋งŒ ์ด๋ฃจ์–ด์ ธ ์žˆ๋Š”์ง€ ํ™•์ธ: ๋ฌธ์ž์—ด.isdecimal()

    • ์•ŒํŒŒ๋ฒณ์œผ๋กœ๋งŒ ์ด๋ฃจ์–ด์ ธ ์žˆ๋Š”์ง€ ํ™•์ธ: ๋ฌธ์ž์—ด.isalpha()

    • ์ˆซ์ž+์•ŒํŒŒ๋ฒณ์œผ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋Š”์ง€ ํ™•์ธ: ๋ฌธ์ž์—ด.isalnum()


  • XOR ์—ฐ์‚ฐ
    • ^ ์—ฐ์‚ฐ์€ intํ˜• ๋ณ€์ˆ˜์—๋งŒ ๊ฐ€๋Šฅ, '0111'๊ณผ ๊ฐ™์€ ๋ฌธ์ž์—ด์—๋Š” ๋ถˆ๊ฐ€

      # ๊ฐ’์ด 0์ด๋ฉด 1๋กœ, 1์ด๋ฉด 0์œผ๋กœ ๋งŒ๋“ค๊ธฐ
      num = 0
      print(num ^ 1)   # 1
      num1 = 7    # 0111 (2์ง„๋ฒ•)
      num2 = 8    # 1000 (2์ง„๋ฒ•)
      print(num1 ^ num2)  # 15 (10์ง„๋ฒ•) == 1111 (2์ง„๋ฒ•)

  • Shift ์—ฐ์‚ฐ

    : bit๋ฅผ ํ•œ์นธ์”ฉ ๋ฐ€๊ธฐ

    num = 8 # 1000 (2์ง„๋ฒ•)
    print(num >> 1) # 4 (10์ง„๋ฒ•) == 0100 (2์ง„๋ฒ•)
    print(num >> 2) # 2 (10์ง„๋ฒ•) == 0010 (2์ง„๋ฒ•)

  • ์ฐจ์ง‘ํ•ฉ ๊ตฌํ•˜๊ธฐ

    • ์ฝ”๋“œ1. set์œผ๋กœ ๋นผ๊ธฐ
      lis1 = ['a', 'b', 'b', 'c']
      lis2 = ['b', 'd']
      result = set(lis1) - set(lis2)  
      result = list(result) # ['a', 'c']
    • ์ฝ”๋“œ2. set์˜ difference_update() ์ด์šฉ
      x = {"a", "b", "c"}
      y = {"d", "e", "a"}
      
      x.difference_update(y)
      print(x)    # {'c', 'b'}

collections ๋ชจ๋“ˆ
  • defaultdict
    • default ๊ฐ’์„ ์„ค์ •ํ•˜์—ฌ ๋”•์…”๋„ˆ๋ฆฌ๋ฅผ ์ƒ์„ฑ
    • ์–ด๋–ค ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋ฉด ํŠน์ • key์˜ value๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ๊ฒฝ์šฐ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ
      dic = collections.defaultdict(int)  # default ๊ฐ’ : 0
      dic['A'] += 1 # ์›๋ž˜๋Œ€๋กœ๋ผ๋ฉด ์กด์žฌํ•˜์ง€ ์•Š๋Š” key ๊ฐ’์ด๋ฏ€๋กœ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€๋งŒ, {'A': 1}์ด ๋จ

  • Counter
    1. ์›์†Œ์˜ ๋นˆ๋„ ์„ธ๊ธฐ

      from collections import Counter
      
      lis = ['a', 'b', 'b', 'c', 'b']
      
      # ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•
      Counter(lis)   # Counter({'b': 3, 'a': 1, 'c': 1})
      
      # List(Tuple) ํ˜•ํƒœ๋กœ ์ „์ฒด ๋ฐ˜ํ™˜ํ•˜๊ธฐ
      Counter(lis).most_common()   # [('b', 3), ('a', 1), ('c', 1)]
      
      # List(Tuple) ํ˜•ํƒœ๋กœ ๋นˆ๋„ ์ˆ˜ ์ƒ์œ„ k๊ฐœ ๋ฐ˜ํ™˜ํ•˜๊ธฐ
      Counter(lis).most_common(2)  # [('b', 3), ('a', 1)]
    2. ๋‘ ๋ฆฌ์ŠคํŠธ ๋นผ๊ธฐ (์ฐจ์ง‘ํ•ฉ)

      • ์ฝ”๋“œ1) ์ค‘๋ณต ์›์†Œ ์ œ๊ฑฐ
        lis1 = ['a', 'b', 'b', 'c']
        lis2 = ['b', 'd']
        result = set(lis1) - set(lis2)  
        result = list(result) # ['a', 'c']
      • ์ฝ”๋“œ2) ์ค‘๋ณต ์›์†Œ ์œ ์ง€
        from collections import Counter
        
        lis1 = ['a', 'b', 'b', 'c']
        lis2 = ['b', 'd']
        result = Counter(lis1) - Counter(lis2)    # Counter({'a': 1, 'b': 1, 'c': 1})

  • OrderedDict
    • ๋”•์…”๋„ˆ๋ฆฌ์˜ ์ž…๋ ฅ ์ˆœ์„œ๋ฅผ ์œ ์ง€

    • Python 3.7 ์ด์ƒ๋ถ€ํ„ฐ๋Š” ์ž๋™์œผ๋กœ ์ž…๋ ฅ ์ˆœ์„œ๊ฐ€ ์œ ์ง€๋˜์ง€๋งŒ, ํ˜น์‹œ ๋ชจ๋ฅผ ์ƒํ™ฉ์„ ์œ„ํ•ด ์‚ฌ์šฉํ•˜์ž.

      collections.OrderedDict({'c': 1, 'a': 5, 'b': 4}) # ๋”•์…”๋„ˆ๋ฆฌ ํ˜•ํƒœ ์œ ์ง€


  • deque
    • pop ์—ฐ์‚ฐ์„ ์ž์ฃผ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ, ๋ฆฌ์ŠคํŠธ ๋Œ€์‹  deque๋ฅผ ์ด์šฉํ•˜๋ฉด ์†๋„๋ฅผ ํ›จ์”ฌ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.

    • append(), popleft(), pop(), appendleft() ์—ฐ์‚ฐ์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋Š” ๋ชจ๋‘ O(1)

      • ์ฐธ๊ณ : List์˜ pop(0)๋Š” O(n)
    • rotate(k): k๊ฐ€ ์–‘์ˆ˜์ด๋ฉด ์˜ค๋ฅธ์ชฝ์œผ๋กœ k์นธ ํšŒ์ „, k๊ฐ€ ์Œ์ˆ˜์ด๋ฉด ์™ผ์ชฝ์œผ๋กœ k์นธ ํšŒ์ „

      from collections import deque
      
      q = deque([1,3,5])
      
      q.pop() # ๋งจ ๋’ค ์›์†Œ pop
      q.popleft() # ๋งจ ์•ž ์›์†Œ pop, ๋ฆฌ์ŠคํŠธ์˜ pop(0)๊ณผ ๋™์ผํ•œ ์—ญํ• 
      
      q.append(10) # ๋งจ ๋’ค์— ์›์†Œ๋ฅผ ์‚ฝ์ž…
      q.appendleft(10) # ๋งจ ์•ž์— ์›์†Œ๋ฅผ ์‚ฝ์ž…
      
      q.rotate(1) # ์˜ค๋ฅธ์ชฝ์œผ๋กœ ํ•œ์นธ์”ฉ ์ด๋™ (ex: [1,3,5] -> [5,1,3])
      q.rotate(-1) # ์™ผ์ชฝ์œผ๋กœ ํ•œ์นธ์”ฉ ์ด๋™  (ex: [1,3,5] -> [3,5,1])

์†Œ์ˆ˜ ์ฐพ๊ธฐ
  • 2๋ถ€ํ„ฐ ์ œ๊ณฑ๊ทผ๊นŒ์ง€ ๋‚˜๋ˆ„์–ด๋–จ์–ด์ง€๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ

    # ๊ธฐ๋ณธ ์ฝ”๋“œ
    def isPrime(num):
        for i in range(2, int(num**0.5) + 1):
            if num % i == 0:
                return False
        return True
    # ๋” ํšจ์œจ์ ์ธ ์ฝ”๋“œ
    def isPrime(num):
        if num % 2 == 0:
            return False
        for i in range(3, int(num**0.5) + 1, 2):
            if num % i == 0:
                return False
        return True
  • ์—๋ผํ† ์Šคํ…Œ๋„ค์Šค์˜ ์ฒด

    : ์ฃผ์–ด์ง„ ๋ฒ”์œ„์˜ ๊ฐ’๋“ค ์ค‘ ์†Œ์ˆ˜๋ฅผ ๋ชจ๋‘ ์ฐพ์•„์•ผํ•  ๋•Œ, 2๋ถ€ํ„ฐ์˜ ๋ฐฐ์ˆ˜๋“ค์„ ๋ชจ๋‘ ์ œ์™ธ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•

    # 1๋ถ€ํ„ฐ 100๊นŒ์ง€์˜ ์ˆ˜ ์ค‘ ์†Œ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•˜์‹œ์˜ค.
    
    n = 100
    primes = [True] * (n+1) # [0]๋Š” ์‚ฌ์šฉ์•ˆํ•จ
    primes[1] = False   # 1์€ False ์ฒ˜๋ฆฌ
    
    for i in range(2, int(n**0.5)+1): # 2 ~ โˆšn
        # i์˜ ๋ฐฐ์ˆ˜๋“ค์„ False ์ฒ˜๋ฆฌํ•˜๊ธฐ (i ์ž์‹ ์€ X)
        for idx in range(i*2, n+1, i):
            primes[idx] = False
    
    # ์†Œ์ˆ˜๋“ค์„ ์ถœ๋ ฅ
    for idx in range(1, n+1):
        if primes[idx]:
            print(idx)

์•ฝ์ˆ˜ ๊ตฌํ•˜๊ธฐ

๋ฐฉ๋ฒ•1: ํ•ด๋‹น ๊ฐ’(n)๊นŒ์ง€์˜ ๋ชจ๋“  ๊ฐ’์„ ํ™•์ธํ•˜๊ธฐ => ๋น„ํšจ์œจ์ 

๋ฐฉ๋ฒ•2: โˆšn๊นŒ์ง€์˜ ๋ชจ๋“  ๊ฐ’ i๋ฅผ ํ™•์ธํ•˜๋Š”๋ฐ, ์ด ๋•Œ ๋Œ€์‘๋˜๋Š” n//i ๊ฐ’๋„ ๋„ฃ์–ด์ค€๋‹ค (์ œ๊ณฑ์ˆ˜์ธ์ง€ ํ™•์ธํ•˜๊ณ  ๋„ฃ๊ธฐ)

div_list = []
for i in range(1, int(n**0.5)+1):
    if n % i == 0:    # i๋Š” n์˜ ์•ฝ์ˆ˜
        div_list.append(i)
        if n // i != i:   # n//i๋„ n์˜ ์•ฝ์ˆ˜
            div_list.append(n//i)
div_list = sorted(div_list)   # ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ

  • +) ์•ฝ์ˆ˜์˜ ๊ฐœ์ˆ˜๊ฐ€ ํ™€์ˆ˜์ธ์ง€ ์ง์ˆ˜์ธ์ง€ ๊ตฌํ•˜๊ธฐ
    • ํ•ด๋‹น ๊ฐ’์ด ์ œ๊ณฑ์ˆ˜์ด๋ฉด ์•ฝ์ˆ˜์˜ ๊ฐœ์ˆ˜๋Š” ํ™€์ˆ˜, ์ œ๊ณฑ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ฉด ์•ฝ์ˆ˜์˜ ๊ฐœ์ˆ˜๋Š” ์ง์ˆ˜
      • ์ œ๊ณฑ์ˆ˜ ํŒ๋ณ„ : if int(n**0.5) == n**0.5:

์ด์ฐจ์› ๋ฐฐ์—ด ํšŒ์ „์‹œํ‚ค๊ธฐ
def rotate(arr):    # arr๋Š” ์ด์ฐจ์› ๋ฐฐ์—ด
    row, col = len(arr), len(arr[0])
    rotated_arr = [[0] * row for _ in range(col)]
    for i in range(row):
        for j in range(col):
            rotated_arr[j][row-1-i] = arr[i][j] # ํ•ต์‹ฌ!
    return rotated_arr

DFS / BFS
  • DFS

    • ๊นŠ๊ฒŒ ํƒ์ƒ‰
    • ์žฌ๊ท€ํ•จ์ˆ˜ or Stack์„ ์ด์šฉํ•ด ๊ตฌํ˜„
    • ์‹œ๊ฐ„๋ณต์žก๋„: O(V+E)
      • V๋Š” ๋…ธ๋“œ ์ˆ˜, E๋Š” ๊ฐ„์„  ์ˆ˜
    # ์žฌ๊ท€ํ•จ์ˆ˜๋กœ ๊ตฌํ˜„
    
    def dfs(node):
        visited[node] = True
        print(node, end=' ')    # ์ถœ๋ ฅ
        for adj_node in graph[node]:
            if not visited[adj_node]:
                dfs(adj_node)
    
    n = 5
    graph = [
        [],     # [0]์€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ
        [2,3],
        [1,4,5],
        [1],
        [2,5],
        [2,4],
    ]
    visited = [False] * (n+1)   # [0]์€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ
    dfs(1)   # ์‹œ์ž‘ ๋…ธ๋“œ: 1
    # ์ถœ๋ ฅ ๊ฒฐ๊ณผ: 1 2 4 5 3

  • BFS

    • ๋„“๊ฒŒ ํƒ์ƒ‰
    • Queue๋ฅผ ์ด์šฉํ•ด ๊ตฌํ˜„
    • ์‹œ๊ฐ„๋ณต์žก๋„: O(V+E)
      • V๋Š” ๋…ธ๋“œ ์ˆ˜, E๋Š” ๊ฐ„์„  ์ˆ˜
    • ์ตœ๋‹จ ๊ฒฝ๋กœ ์ฐพ์„ ๋•Œ ์ž์ฃผ ์‚ฌ์šฉ
    from collections import deque
    
    def bfs(start):
        q = deque()
        q.append(start)
        visited[start] = True
    
        while q:
            node = q.popleft()
            print(node, end=' ')    # ์ถœ๋ ฅ
            for adj_node in graph[node]:
                if not visited[adj_node]:
                    q.append(adj_node)
                    visited[adj_node] = True
    
    n = 5
    graph = [
        [],     # [0]์€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ
        [2,3],
        [1,4,5],
        [1],
        [2,5],
        [2,4],
    ]
    visited = [False] * (n+1)   # [0]์€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ
    bfs(1)   # ์‹œ์ž‘ ๋…ธ๋“œ: 1
    # ์ถœ๋ ฅ ๊ฒฐ๊ณผ: 1 2 3 4 5

    • BFS์™€ ๋‹ค์ต์ŠคํŠธ๋ผ์˜ ์ฐจ์ด์ 
      • BFS์™€ ๋‹ค์ต์ŠคํŠธ๋ผ ๋ชจ๋‘ ๊ทธ๋ž˜ํ”„์—์„œ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.
      • BFS์—์„œ๋Š” ๊ฐ„์„ ์˜ ์ˆ˜๋ฅผ ์ตœ์†Œ๋กœ ํ•˜๋Š” ๋ฐ˜๋ฉด, ๋‹ค์ต์ŠคํŠธ๋ผ์—์„œ๋Š” ๊ฐ€์ค‘์น˜์˜ ํ•ฉ์„ ์ตœ์†Œ๋กœ ํ•œ๋‹ค.
        • ์ฆ‰, ๋Œ์•„๊ฐ€๋Š” ๊ฒฝ๋กœ์—ฌ๋„ ๊ฐ€์ค‘์น˜ ํ•ฉ์ด ์ตœ์†Œ์ด๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค๋ฉด ๋‹ค์ต์ŠคํŠธ๋ผ๋ฅผ ์‚ฌ์šฉ
      • BFS์—์„œ๋Š” ๊ฐ€์ค‘์น˜๊ฐ€ ์—†๊ฑฐ๋‚˜ ๋™์ผํ•œ ๋ฐ˜๋ฉด, ๋‹ค์ต์ŠคํŠธ๋ผ์—์„œ๋Š” ๊ฐ€์ค‘์น˜๊ฐ€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค.
      • BFS์—์„œ๋Š” Queue๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ˜๋ฉด, ๋‹ค์ต์ŠคํŠธ๋ผ์—์„œ๋Š” Priority Queue ๋˜๋Š” Heap์„ ์‚ฌ์šฉํ•œ๋‹ค.
      • ํ˜„์žฌ ๋…ธ๋“œ์˜ ์ธ์ ‘ ๋…ธ๋“œ๋“ค์„ ํƒ์ƒ‰ํ•  ๋•Œ, BFS์—์„œ๋Š” ๋ฐฉ๋ฌธํ•œ ์ ์ด ์—†๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฐ˜๋ฉด, ๋‹ค์ต์ŠคํŠธ๋ผ์—์„œ๋Š” ์ตœ์†Œ ๊ฑฐ๋ฆฌ์ธ์ง€ ํ™•์ธํ•œ๋‹ค.

Queue
  • FIFO (First In First Out)

  • ์ผ๋ฐ˜์ ์œผ๋กœ deque๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„

    • ์‚ฝ์ž…: append() (appendleft()๋„ ์žˆ์Œ)
    • ์ œ๊ฑฐ: popleft() (pop()๋„ ์žˆ์Œ)
      from collections import deque
      
      queue = deque()
      queue.append(3)
      queue.append(1)
      queue.popleft() # 3
    • ์ฃผ์˜) ์›์†Œ ์ถ”๊ฐ€ ์‹œ, append()์— ๋ฆฌ์ŠคํŠธ๋ฅผ ๋„ฃ์œผ๋ฉด ๋ฆฌ์ŠคํŠธ ์ „์ฒด๋ฅผ ํ•˜๋‚˜์˜ ์›์†Œ๋กœ ์ถ”๊ฐ€ํ•˜๋ฏ€๋กœ extend()๋ฅผ ์‚ฌ์šฉ
      queue = deque()
      queue.append(0)
      queue.append([1,2,3])
      # queue: deque([0,[1,2,3]])
      
      queue = deque()
      queue.append(0)
      queue.extend([1,2,3])
      # queue: deque([0,1,2,3])
  • ์šฐ์„ ์ˆœ์œ„ ํ (Priority Queue)

    : ๋‹จ์ˆœํžˆ ๋จผ์ € ๋“ค์–ด์˜จ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๊ณ , ์ €์žฅ๋œ ๊ฐ’๋“ค์„ ์ •๋ ฌํ•ด์„œ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•จ

    • ์ผ๋ฐ˜์ ์œผ๋กœ PriorityQueue๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„

      • ์‚ฝ์ž…: put()
      • ์ œ๊ฑฐ: get()
      • ์˜ค๋ฆ„์ฐจ์ˆœ ๋ง๊ณ  ๋‹ค๋ฅธ ๊ธฐ์ค€์œผ๋กœ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์‹ถ์œผ๋ฉด, (์šฐ์„ ์ˆœ์œ„, ๊ฐ’) ํŠœํ”Œ๋กœ ์ €์žฅ
        • ex: (1, 'lemon')
        • ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋™์ผํ•œ ํŠœํ”Œ๋“ค์€ ๊ฐ’์— ๋”ฐ๋ผ ์ •๋ ฌ๋จ
      • ์ฃผ์˜) while queue: ํ•˜๋ฉด ํ•ญ์ƒ True์ด๋ฏ€๋กœ while queue.qsize() > 0:์œผ๋กœ ์‚ฌ์šฉ
      from queue import PriorityQueue
      
      queue = PriorityQueue()
      
      queue.put(3)
      queue.put(1)
      queue.put(5)
      print(queue.get())  # 1
      print(queue.get())  # 3
      print(queue.get())  # 5
      from queue import PriorityQueue
      
      queue = PriorityQueue()
      
      queue.put((2, 'apple'))
      queue.put((1, 'lemon'))
      queue.put((1, 'blueberry'))
      print(queue.get())  # (1, 'blueberry')
      print(queue.get())  # (1, 'lemon')
      print(queue.get())  # (2, 'apple')
    • heapq๋กœ๋„ ๊ตฌํ˜„ ๊ฐ€๋Šฅ

      import heapq
      
      heap = []
      heapq.heappush(heap, 3)
      heapq.heappush(heap, 1)
      heapq.heappop(heap)   # 1
      import heapq
      
      heap = [3,5,1,4,2]
      heapq.heapify(heap)
      heapq.heappop(heap)   # 1

Heap
min heap.png
  • ์ตœ์†Œ๊ฐ’/์ตœ๋Œ€๊ฐ’์„ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ฐพ์•„์•ผํ•  ๋•Œ ์œ ์šฉํ•จ

  • Heap์€ ์™„์ „์ด์ง„ํŠธ๋ฆฌ์ด๋ฏ€๋กœ ๋†’์ด๊ฐ€ logn => ๋ชจ๋“  ๋…ธ๋“œ์— ๋Œ€ํ•ด ์—ฐ์‚ฐ์„ ํ•ด์•ผํ•˜๋ฏ€๋กœ ์‹œ๊ฐ„๋ณต์žก๋„๋Š” O(nlogn)

  • pop ์—ฐ์‚ฐ์„ ํ•˜๋ฉด ๋ฃจํŠธ ๋…ธ๋“œ์˜ ๊ฐ’์ด ๋ฐ˜ํ™˜๋จ (min heap์ด๋ฉด ์ตœ์†Œ๊ฐ’, max heap์ด๋ฉด ์ตœ๋Œ€๊ฐ’)

  • heapq ๋ชจ๋“ˆ์€ min heap๋งŒ์„ ์ง€์›ํ•จ

    • max heap์„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค๋ฉด ์›์†Œ๋ฅผ ๋ชจ๋‘ ์Œ์ˆ˜๋กœ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋จ
    import heapq
    
    # heap์„ ๋งŒ๋“ค๋ฉด์„œ ์›์†Œ๋ฅผ ํ•˜๋‚˜์”ฉ ์ง‘์–ด๋„ฃ๊ธฐ
    heap = []
    heapq.heappush(heap, 2)
    heapq.heappush(heap, 1)
    heapq.heappop(heap)  # 1
    import heapq
    
    # ๋ฆฌ์ŠคํŠธ๋ฅผ ํ•œ๋ฒˆ์— heap์œผ๋กœ ๋งŒ๋“ค๊ธฐ
    heap = [2, 1]
    heapq.heapify(heap)
    heapq.heappop(heap)  # 1
  • heap์„ ๋น„์šฐ๋ ค๋ฉด

    • heap = []๋กœ ๋ฆฌ์ŠคํŠธ๋ฅผ ์žฌ์ƒ์„ฑํ•ด์ฃผ๋ฉด ๋จ
  • ์ฃผ์˜) heapify()์˜ ํšจ๊ณผ

    • ๋ฆฌ์ŠคํŠธ๊ฐ€ ์ •๋ ฌ๋จ (X)
    • ํ•ญ์ƒ ์ตœ์†Œ๊ฐ’์„ root์— ๋ฐฐ์น˜ํ•จ์œผ๋กœ์จ heappop()์„ ํ†ตํ•ด ์ตœ์†Œ๊ฐ’์„ ์–ป์Œ (O)
    heap = [9,1,3,8]
    heapq.heapify(heap) # [1, 8, 3, 9]
    heapq.heappop(heap) # 1
    heapq.heappop(heap) # 3
    heapq.heappop(heap) # 8
    heapq.heappop(heap) # 9
    
    heap = [(9, 1), (1 ,2), (3, 4), (8, 7)]
    heapq.heapify(heap) # [(1, 2), (8, 7), (3, 4), (9, 1)]
    heapq.heappop(heap) # (1, 2)
    heapq.heappop(heap) # (3, 4)
    heapq.heappop(heap) # (8, 7)
    heapq.heappop(heap) # (9, 1)
  • Binary Search Tree์˜ ์„ฑ์งˆ๊ณผ ํ—ท๊ฐˆ๋ฆฌ์ง€ ๋ง ๊ฒƒ!


Tree
  • Binary Tree
    • ์ž์‹ ๋…ธ๋“œ์˜ ์ˆ˜๋Š” ์ตœ๋Œ€ 2๊ฐœ
    • ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฆฌ์ŠคํŠธ๋กœ ๊ตฌํ˜„
      • root ๋…ธ๋“œ์˜ index๋Š” 1
      • index๋กœ ๋…ธ๋“œ๋ฅผ ์ด๋™ํ•˜๋Š” ๋ฐฉ๋ฒ•
        • ๋ฃจํŠธ ๋…ธ๋“œ๋กœ ์ด๋™ => index = 1
        • ๋ถ€๋ชจ ๋…ธ๋“œ๋กœ ์ด๋™ => index = index / 2
        • ์™ผ์ชฝ ์ž์‹ ๋…ธ๋“œ๋กœ ์ด๋™ => index = index * 2
        • ์˜ค๋ฅธ์ชฝ ์ž์‹ ๋…ธ๋“œ๋กœ ์ด๋™ => index = index * 2 + 1
    • ์‹œ๊ฐ„๋ณต์žก๋„: O(logn) (์ตœ์•…์˜ ๊ฒฝ์šฐ skewed tree์ด๋ฉด O(n))

  • Binary Search Tree

    • ์ž์‹ ๋…ธ๋“œ์˜ ์ˆ˜๋Š” ์ตœ๋Œ€ 2๊ฐœ
    • ์–ด๋–ค ๋…ธ๋“œ์˜ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋Š” ํ•ด๋‹น ๋…ธ๋“œ ๊ฐ’๋ณด๋‹ค ์ž‘์€ ๊ฐ’์„ ๊ฐ–๋Š” ๋…ธ๋“œ๋“ค๋กœ ์ด๋ฃจ์–ด์ง
    • ์–ด๋–ค ๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋Š” ํ•ด๋‹น ๋…ธ๋“œ ๊ฐ’๋ณด๋‹ค ํฐ ๊ฐ’์„ ๊ฐ–๋Š” ๋…ธ๋“œ๋“ค๋กœ ์ด๋ฃจ์–ด์ง
    binary search tree.png

์ด์ง„ ํƒ์ƒ‰ (Binary Search)

: start, mid, end๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ, mid์˜ ๊ฐ’์ด ์ฐพ๋Š” ๊ฐ’๊ณผ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธ์„ ๋ฐ˜๋ณตํ•˜๋Š” ๋ฐฉ๋ฒ•

  • ์กฐ๊ฑด: ๋ฆฌ์ŠคํŠธ๊ฐ€ ์ •๋ ฌ๋˜์–ด ์žˆ์–ด์•ผํ•จ!
  • ๊ฐ’์˜ ๊ฐฏ์ˆ˜ or ๋ฒ”์œ„๊ฐ€ ์—„์ฒญ ํด ๋•Œ ๋งŽ์ด ์‚ฌ์šฉ
  • ์‹œ๊ฐ„๋ณต์žก๋„: O(logn)
  • ์ฝ”๋”ฉํ…Œ์ŠคํŠธ ์ž์ฃผ ์ถœ์ œ

  • ์ฝ”๋“œ1. ์žฌ๊ท€๋กœ ๊ตฌํ˜„
    arr = [8,4,0,2,6]
    arr.sort() # ์ •๋ ฌ ํ•„์ˆ˜!
    target = 4
            
    def binary_search(start, end):
        if start > end:
            return -1
        
        mid = (start + end) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] > target:
            # end = mid - 1
            binary_search(start, mid - 1)
        else:
            # start = mid + 1
            binary_search(mid + 1, end)
            
    binary_search(0, len(arr)-1) # 2
  • ์ฝ”๋“œ2. ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๊ตฌํ˜„
    arr = [8,4,0,2,6]
    arr.sort() # ์ •๋ ฌ ํ•„์ˆ˜!
    target = 4
    
    def binary_search(start, end):
        while start <= end:
            mid = (start + end) // 2
            if arr[mid] == target:
                return mid
            elif arr[mid] > target:
                end = mid - 1
            else:
                start = mid + 1
        return -1 # ํ•ด๋‹น ๊ฐ’์ด ์—†๋Š” ๊ฒฝ์šฐ
        
    binary_search(0, len(arr)-1)  # 2

ํˆฌ ํฌ์ธํ„ฐ

: start ํฌ์ธํ„ฐ์™€ end ํฌ์ธํ„ฐ๋ฅผ ์„ค์ •ํ•˜๊ณ  ๊ฐ’์˜ ๋ฒ”์œ„๋ฅผ ๋”ฐ์ ธ ํฌ์ธํ„ฐ๋ฅผ ํ•œ์นธ์”ฉ ์ด๋™์‹œํ‚ด

  • ์‹œ๊ฐ„๋ณต์žก๋„: O(n)

  • ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ ๋‚ฎ๊ธฐ ๋•Œ๋ฌธ์—, ์ฃผ๋กœ ๊ฐ’์˜ ๋ฒ”์œ„๊ฐ€ ํฌ๊ฑฐ๋‚˜ ๊ฐฏ์ˆ˜๊ฐ€ ๋งŽ์„ ๋•Œ ์‚ฌ์šฉํ•จ

  • ์˜ˆ์ œ1. k๋ฅผ ์—ฐ์†๋œ ์ˆ˜๋“ค์˜ ํ•ฉ์œผ๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜

    start, end = 1, 1 # ์ž์—ฐ์ˆ˜์—ฌ์•ผํ•˜๋ฏ€๋กœ 1๋กœ ํ• ๋‹น
    sum = 1
    answer = 1    # k ํ•˜๋‚˜๋กœ๋งŒ ๊ตฌ์„ฑ๋œ ๊ฒฝ์šฐ๋ฅผ ํฌํ•จ
    while end < k:
        if sum < k:
            end += 1
            sum += end
        elif sum == k:
            answer += 1
            end += 1
            sum += end
        else:
            start += 1
            sum -= start
    print(answer)
  • ์˜ˆ์ œ2. k๋ฅผ ๋‘ ์ˆ˜์˜ ํ•ฉ์œผ๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜

    numbers = [2, 6, 4, 1, 5, 3]
    numbers.sort()    # [1, 2, 3, 4, 5, 6]
    
    start, end = 0, len(numbers)-1
    answer = 0
    while start < end:
        if numbers[start] + numbers[end] > k:
            end -= 1
        elif numbers[start] + numbers[end] == k:
            answer += 1
            end -= 1
        else:
            start += 1
    print(answer)

์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜
  1. ๋ณ‘ํ•ฉ(merge) ์ •๋ ฌ

    : ๋ฆฌ์ŠคํŠธ๋ฅผ ๋‘ ๊ฐœ์˜ ๋ถ€๋ถ„์ง‘ํ•ฉ์œผ๋กœ ๋ฐ˜๋ณตํ•ด ๋‚˜๋ˆ„๊ณ , ์ด๋ฏธ ์ •๋ ฌ๋œ ๋ถ€๋ถ„์ง‘ํ•ฉ๋“ค์„ ๋ณ‘ํ•ฉํ•˜๋ฉฐ ์ •๋ ฌํ•˜๋Š” ๋ฐฉ์‹

    • ์žฌ๊ท€ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋ฆฌ์ŠคํŠธ๋ฅผ ์ชผ๊ฐ  ํ›„, ํˆฌ ํฌ์ธํ„ฐ๋ฅผ ์ด์šฉํ•ด ๋‘ ๋ถ€๋ถ„์ง‘ํ•ฉ์—์„œ ์ž‘์€ ๊ฐ’๋ถ€ํ„ฐ ์ง‘์–ด๋„ฃ์Œ
    • ์‹œ๊ฐ„๋ณต์žก๋„: O(nlogn)
    • ์ฝ”๋”ฉํ…Œ์ŠคํŠธ์—์„œ ์ž์ฃผ ๋“ฑ์žฅ
    arr = [3,5,4,1,2]
    
    def merge_sort(arr):
        if len(arr) <= 1:
            return arr
    
        # ๋ฆฌ์ŠคํŠธ ์ชผ๊ฐœ๊ธฐ
        mid = len(arr) // 2
        left_arr = merge_sort(arr[:mid])
        right_arr = merge_sort(arr[mid:])
        
        # ํˆฌ ํฌ์ธํ„ฐ๋ฅผ ํ™œ์šฉํ•ด ์ž‘์€ ๊ฐ’๋ถ€ํ„ฐ ์ง‘์–ด๋„ฃ์Œ
        merged_arr = []
        l, r = 0, 0
        while l < len(left_arr) and r < len(right_arr):
            if left_arr[l] < right_arr[r]:
                merged_arr.append(left_arr[l])
                l += 1
            else:
                merged_arr.append(right_arr[r])
                r += 1
        # ๋‚จ์€ ์›์†Œ๋“ค ์‚ฝ์ž…
        if l < len(left_arr):
            merged_arr += left_arr[l:]
        else:
            merged_arr += right_arr[r:]
            
        return merged_arr
  2. ๋ฒ„๋ธ”(bubble) ์ •๋ ฌ

    : ์ธ์ ‘ ๊ฐ’๋ผ๋ฆฌ ๋น„๊ตํ•ด์„œ swapํ•˜๋ฉฐ ์ •๋ ฌํ•˜๋Š” ๋ฐฉ์‹

    • ์‹œ๊ฐ„๋ณต์žก๋„: O(n^2)
    arr = [3,5,4,1,2]
    n = len(arr)
    for i in range(n-1):
        for j in range(n-1-i):
            if arr[j] > arr[j+1]:   # swap
                arr[j], arr[j+1] = arr[j+1], arr[j]
  3. ์‚ฝ์ž…(insertion) ์ •๋ ฌ

    : ํŠน์ • ๊ฐ’์„ ์ด๋ฏธ ์ •๋ ฌ๋œ ์˜์—ญ์˜ ๊ฐ’๋“ค๊ณผ ํ•˜๋‚˜์”ฉ ๋น„๊ตํ•ด์„œ swapํ•˜๋ฉด์„œ ์ ์ ˆํ•œ ์œ„์น˜์— ์‚ฝ์ž…ํ•˜๋Š” ๋ฐฉ์‹

    • i๋Š” index 1๋ถ€ํ„ฐ ์˜ค๋ฅธ์ชฝ์œผ๋กœ, j๋Š” index i๋ถ€ํ„ฐ ์™ผ์ชฝ์œผ๋กœ ์ด๋™.
    • ์‹œ๊ฐ„๋ณต์žก๋„: O(n^2)
    arr = [3,5,4,1,2]
    n = len(arr)
    for i in range(1, n):
        for j in range(i, 0, -1):
            if arr[j-1] > arr[j]:   # swap
                arr[j-1], arr[j] = arr[j], arr[j-1]
            else:
                break
  4. ํ€ต(quick) ์ •๋ ฌ

    : pivot์„ ์„ ์ •ํ•ด ํ•ด๋‹น ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ๋Œ€์†Œ๋น„๊ตํ•˜๋ฉด์„œ ์ •๋ ฌํ•˜๋Š” ๋ฐฉ์‹

    • ์žฌ๊ท€ํ•จ์ˆ˜ ์ด์šฉ
    • ์‹œ๊ฐ„๋ณต์žก๋„: O(nlogn) (๋กœ ์•Œ๊ณ  ์žˆ์œผ๋ฉด ๋˜๊ณ  ์ตœ์•…์˜ ๊ฒฝ์šฐ O(n^2)์ž„)
    arr = [3,5,4,1,2]
    
    def quick_sort(arr):
        if len(arr) <= 1:
            return arr
        
        pivot = arr[0]  # ์ฒซ๋ฒˆ์งธ ์›์†Œ๋ฅผ pivot์œผ๋กœ ์„ค์ •
        small_arr = [x for x in arr[1:] if x <= pivot]
        large_arr = [x for x in arr[1:] if x > pivot]
        
        return quick_sort(small_arr) + [pivot] + quick_sort(large_arr)
    
    print(quick_sort(arr))  # [1,2,3,4,5]
  5. ์„ ํƒ(selection) ์ •๋ ฌ

    : ๋‚จ์€ ๋ถ€๋ถ„์—์„œ ์ตœ์†Œ๊ฐ’์„ ์ฐพ๊ณ  ๋‚จ์€ ๋ถ€๋ถ„์˜ ๋งจ ์•ž์— ์žˆ๋Š” ๋ฐ์ดํ„ฐ์™€ swapํ•˜๋ฉฐ ์ •๋ ฌํ•˜๋Š” ๋ฐฉ์‹ (์ตœ๋Œ€๊ฐ’๋„ ๊ฐ€๋Šฅ)

    • ์‹œ๊ฐ„๋ณต์žก๋„: O(n^2)
    • ๊ตฌํ˜„์ด ๋ณต์žกํ•˜๊ณ  ์‹œ๊ฐ„๋ณต์žก๋„๋„ ๋†’์•„ ์ฝ”ํ…Œ์—์„œ ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ!

๊ทธ๋ฆฌ๋””(Greedy) ์•Œ๊ณ ๋ฆฌ์ฆ˜

: ํ˜„์žฌ ์ƒํƒœ์—์„œ ์ตœ์„ ์˜ ์„ ํƒ์ง€๊ฐ€ ์ „์ฒด์—์„œ ์ตœ์„ ์˜ ์„ ํƒ์ง€๋ผ๊ณ  ๊ฐ€์ •ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

  • ์ˆ˜ํ–‰ ๊ณผ์ •

    1. ํ˜„์žฌ ์ƒํƒœ์—์„œ ์ตœ์„ ์˜ ํ•ด๋ฅผ ์„ ํƒํ•œ๋‹ค.
    2. ์„ ํƒํ•œ ํ•ด๊ฐ€ ์ „์ฒด ๋ฌธ์ œ์˜ ์ œ์•ฝ ์กฐ๊ฑด์— ๋ฒ—์–ด๋‚˜์ง€ ์•Š๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
    3. ํ˜„์žฌ๊นŒ์ง€ ์„ ํƒํ•œ ํ•ด์˜ ์ง‘ํ•ฉ์ด ์ „์ฒด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
      ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ•œ๋‹ค๋ฉด 1๋ฒˆ์œผ๋กœ ๋Œ์•„๊ฐ€ ๋ฐ˜๋ณตํ•œ๋‹ค.
  • ๋Œ€ํ‘œ ๋ฌธ์ œ: ์ตœ์†Œ ๊ฐฏ์ˆ˜์˜ ๋™์ „์„ ์‚ฌ์šฉํ•ด ์ฃผ์–ด์ง„ ๊ธˆ์•ก ๋งŒ๋“ค๊ธฐ


์œ ๋‹ˆ์˜จ ํŒŒ์ธ๋“œ (union-find)
  • union(a, b)

    • a ๋…ธ๋“œ์˜ ๋Œ€ํ‘œ ๋…ธ๋“œ์™€ b ๋…ธ๋“œ์˜ ๋Œ€ํ‘œ ๋…ธ๋“œ ์ค‘, ๋” ํฐ ๋Œ€ํ‘œ ๋…ธ๋“œ๋ฅผ ๋” ์ž‘์€ ๋Œ€ํ‘œ ๋…ธ๋“œ์— ์—ฐ๊ฒฐ์‹œํ‚ด
  • find(a)

    • a ๋…ธ๋“œ์˜ ๋Œ€ํ‘œ ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜
    • ์žฌ๊ท€๋ฅผ ํ†ตํ•ด์„œ ๋Œ€ํ‘œ ๋…ธ๋“œ๋ฅผ ์ฐพ์Œ
    • ๋Œ€ํ‘œ ๋…ธ๋“œ๋ฅผ ์ฐพ์€ ํ›„, ์žฌ๊ท€๋ฅผ ๋น ์ ธ๋‚˜์˜ค๋ฉด์„œ ๊ฑฐ์น˜๋Š” ๋ชจ๋“  ๋…ธ๋“œ์˜ ๋Œ€ํ‘œ ๋…ธ๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ•จ => ๊ทธ๋ž˜ํ”„๋ฅผ ์ •๋ˆํ•˜๊ณ  ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ์ค„์ด๋Š” ์—ญํ• ์„ ํ•จ
  • ๊ตฌํ˜„ ์ฝ”๋“œ

    parents = list(range(n + 1))    # ๊ฐ ๋…ธ๋“œ์˜ ๋Œ€ํ‘œ ๋…ธ๋“œ๋ฅผ ์˜๋ฏธ
    
    def find(a):
        if a == parents[a]:  # ๋Œ€ํ‘œ๋…ธ๋“œ
            return a
        else:
            parent_a = find(parents[a])
            parents[a] = parent_a  # ๋Œ€ํ‘œ๋…ธ๋“œ ์—…๋ฐ์ดํŠธ
            return parent_a
      
    def union(a, b):
        parent_a = find(a)
        parent_b = find(b)
        
        if parent_a <= parent_b:
            parents[parent_b] = parent_a
        else:
            parents[parent_a] = parent_b
        # ์•„๋ž˜์ฒ˜๋Ÿผ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ฒŒ ์ฃผ์˜!! ๋Œ€ํ‘œ๋…ธ๋“œ๋ผ๋ฆฌ ์—ฐ๊ฒฐ์„ ํ•ด์•ผํ•จ
        # if a <= b:
        #     parents[b] = parent_a
        # else:
        #     parents[a] = parent_b
  • ์ž์ฃผ ์‹ค์ˆ˜ํ•˜๋Š” ๋ถ€๋ถ„

    • find ์—ฐ์‚ฐ์—์„œ, ์žฌ๊ท€๋ฅผ ๋น ์ ธ๋‚˜์˜ค๋ฉด์„œ ๋ชจ๋“  ๋…ธ๋“œ์˜ ๋Œ€ํ‘œ ๋…ธ๋“œ๋ฅผ ๊ผญ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•จ
    • union ์—ฐ์‚ฐ์—์„œ, a์™€ b ๋…ธ๋“œ๋ผ๋ฆฌ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ a์™€ b์˜ ๋Œ€ํ‘œ๋…ธ๋“œ๋ผ๋ฆฌ ์—ฐ๊ฒฐํ•ด์•ผ ํ•จ

์œ„์ƒ ์ •๋ ฌ

: ์‚ฌ์ดํด์ด ์—†๋Š” ๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„์—์„œ ๋…ธ๋“œ์˜ ์ˆœ์„œ๋ฅผ ์ฐพ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

  • ์ •๋ ฌ ๊ฒฐ๊ณผ๊ฐ€ ์œ ์ผํ•˜์ง€๋Š” ์•Š์Œ

  • ์‹œ๊ฐ„๋ณต์žก๋„: O(V+E)

  • ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

    1. ๊ทธ๋ž˜ํ”„์™€ ๋ณ„๊ฐœ๋กœ, ์ž๊ธฐ ์ž์‹ ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ„์„ ์˜ ์ˆ˜๋ฅผ ์˜๋ฏธํ•˜๋Š” ์ง„์ž…์ฐจ์ˆ˜(in-degree) ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ฆ
    2. ์ง„์ž…์ฐจ์ˆ˜๊ฐ€ 0์ธ ๋…ธ๋“œ๋“ค์„ queue์— ์‚ฝ์ž…
    3. queue์—์„œ ๋…ธ๋“œ๋ฅผ ๋ฝ‘๊ณ  (๊ฒฐ๊ณผ๊ฐ’์— ์ €์žฅ)
      ํ•ด๋‹น ๋…ธ๋“œ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋…ธ๋“œ๋“ค์˜ ์ง„์ž…์ฐจ์ˆ˜๋ฅผ 1 ๊ฐ์†Œ์‹œํ‚ด
      ๊ฐ์†Œ ํ›„ ์ง„์ž…์ฐจ์ˆ˜๊ฐ€ 0์ด ๋œ ๋…ธ๋“œ๋“ค์„ queue์— ์‚ฝ์ž…
    4. queue๊ฐ€ ๋นŒ ๋•Œ๊นŒ์ง€ 3๋ฒˆ ์ž‘์—…์„ ๋ฐ˜๋ณต
    from collections import deque
    
    n = 5
    graph = [
        [],     
        [2,3],  # node 1
        [4,5],  # node 2
        [4],    # node 3
        [5],    # node 4
        [],     # node 5
    ]
    
    # 1๋ฒˆ ์ž‘์—…
    indegree = [0, 0, 1, 1, 2, 2]
    
    # 2๋ฒˆ ์ž‘์—…
    queue = deque()
    for i in range(1, n+1):
        if indegree[i] == 0:
            queue.append(i)
            
    while queue:
        # 3๋ฒˆ ์ž‘์—…
        node = queue.popleft()
        print(node, end=' ')    # ๊ฒฐ๊ณผ ๊ฐ’ ์ถœ๋ ฅ
        for next_node in graph[node]:
            indegree[next_node] -= 1
            if indegree[next_node] == 0:
                queue.append(next_node)

๋‹ค์ต์ŠคํŠธ๋ผ (Dijkstra) ์•Œ๊ณ ๋ฆฌ์ฆ˜

: ํŠน์ • ๋…ธ๋“œ์—์„œ ๋‹ค๋ฅธ ๋ชจ๋“  ๋…ธ๋“œ๋“ค๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•  ๋•Œ ์‚ฌ์šฉ

  • ํŠน์ง•

    • ๋…ธ๋“œ ๊ฐ„ ๊ฑฐ๋ฆฌ๊ฐ€ ์ฃผ์–ด์ง€๋Š” ๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„์—ฌ์•ผ ํ•จ
    • ๊ฑฐ๋ฆฌ๋Š” ๋ชจ๋‘ ์–‘์ˆ˜์—ฌ์•ผ ํ•จ
    • ๊ฐ€์ค‘์น˜์˜ ํ•ฉ์ด ์ตœ์†Œ๊ฐ€ ๋˜๋Š” ๊ฒฝ๋กœ๋ฅผ ์ฐพ์Œ
  • ์‹œ๊ฐ„๋ณต์žก๋„: O(ElogV)

  • ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

    1. (๋…ธ๋“œ, ๊ฑฐ๋ฆฌ)๋ฅผ ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ์— ์ €์žฅํ•ด ๊ทธ๋ž˜ํ”„๋ฅผ ๋งŒ๋“ ๋‹ค.
    2. distance ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค๊ณ , ์ถœ๋ฐœ ๋…ธ๋“œ์˜ ๊ฑฐ๋ฆฌ๋Š” 0, ๋‹ค๋ฅธ ๋…ธ๋“œ๋“ค์˜ ๊ฑฐ๋ฆฌ๋Š” INF๋กœ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.
    3. ๊ฑฐ๋ฆฌ๊ฐ€ ๊ฐ€์žฅ ์ž‘์€ ๋…ธ๋“œ๋ฅผ ์„ ํƒํ•œ๋‹ค.
      • ์ด๋ฅผ ์œ„ํ•ด ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•จ (PriorityQueue / heapq)
      • ํ์— (๊ฑฐ๋ฆฌ, ๋…ธ๋“œ) ์ˆœ์œผ๋กœ ์ €์žฅํ•ด์•ผ ํ•จ
    4. ์„ ํƒํ•œ ๋…ธ๋“œ์— ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋“ค์— ๋Œ€ํ•ด ๊ฑฐ๋ฆฌ๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.
      • distance[adj_node]๊ณผ dist + adj_dist ์ค‘ ๋” ์ž‘์€ ๊ฒƒ
    5. ๋ชจ๋“  ๋…ธ๋“œ๊ฐ€ ์„ ํƒ๋  ๋•Œ๊นŒ์ง€ 3~4๋ฒˆ์„ ๋ฐ˜๋ณตํ•œ๋‹ค.
  • ์ฝ”๋“œ1: heapq๋กœ ๊ตฌํ˜„

    import heapq
    
    graph = [[] for _ in range(n + 1)]
    for _ in range(d):
        src_node, tgt_node, dist = map(int, input().split())
        graph[src_node].append((tgt_node, dist))
    
    INF = 10 ** 5
    distance = [INF] * (n + 1)
    
    # priority queue ๋งŒ๋“ค๊ธฐ
    queue = []
    heapq.heappush(queue, (0, start))   # (๊ฑฐ๋ฆฌ, ๋…ธ๋“œ) ์ˆœ์œผ๋กœ ์ €์žฅ
    distance[start] = 0
    
    # ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜
    while queue:
        dist, node = heapq.heappop(queue)  # ๊ฐ€์žฅ ๊ฑฐ๋ฆฌ๊ฐ€ ์ž‘์€ ๋…ธ๋“œ ๋ฐ˜ํ™˜
        if dist > distance[node]:   # invalid
            continue
        for adj_node, adj_dist in graph[node]:
            if dist + adj_dist < distance[adj_node]:  # ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ์—…๋ฐ์ดํŠธ
            # if distance[node] + adj_dist < distance[adj_node]:  # ์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•˜์ง€ ์•Š๋„๋ก ์ฃผ์˜!
                distance[adj_node] = dist + adj_dist
                heapq.heappush(queue, (distance[adj_node], adj_node))   # (๊ฑฐ๋ฆฌ, ๋…ธ๋“œ) ์ˆœ์œผ๋กœ ์ €์žฅ
  • ์ฝ”๋“œ2: PriorityQueue๋กœ ๊ตฌํ˜„

    from queue import PriorityQueue
    
    graph = [[] for _ in range(n + 1)]
    for _ in range(d):
        src_node, tgt_node, dist = map(int, input().split())
        graph[src_node].append((tgt_node, dist))
    
    INF = 10 ** 5
    distance = [INF] * (n + 1)
    
    # priority queue ๋งŒ๋“ค๊ธฐ
    queue = PriorityQueue()
    queue.put((0, start))   # (๊ฑฐ๋ฆฌ, ๋…ธ๋“œ) ์ˆœ์œผ๋กœ ์ €์žฅ
    distance[start] = 0
    
    # ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜
    while queue.qsize() > 0:
        dist, node = queue.get()  # ๊ฐ€์žฅ ๊ฑฐ๋ฆฌ๊ฐ€ ์ž‘์€ ๋…ธ๋“œ ๋ฐ˜ํ™˜
        if dist > distance[node]:   # invalid
            continue
        for adj_node, adj_dist in graph[node]:
            if dist + adj_dist < distance[adj_node]:  # ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ์—…๋ฐ์ดํŠธ
                distance[adj_node] = dist + adj_dist
                queue.put((distance[adj_node], adj_node))   # (๊ฑฐ๋ฆฌ, ๋…ธ๋“œ) ์ˆœ์œผ๋กœ ์ €์žฅ

  • BFS์™€ ๋‹ค์ต์ŠคํŠธ๋ผ์˜ ์ฐจ์ด์ 
    • BFS์™€ ๋‹ค์ต์ŠคํŠธ๋ผ ๋ชจ๋‘ ๊ทธ๋ž˜ํ”„์—์„œ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.
    • BFS์—์„œ๋Š” ๊ฐ„์„ ์˜ ์ˆ˜๋ฅผ ์ตœ์†Œ๋กœ ํ•˜๋Š” ๋ฐ˜๋ฉด, ๋‹ค์ต์ŠคํŠธ๋ผ์—์„œ๋Š” ๊ฐ€์ค‘์น˜์˜ ํ•ฉ์„ ์ตœ์†Œ๋กœ ํ•œ๋‹ค.
      • ์ฆ‰, ๋Œ์•„๊ฐ€๋Š” ๊ฒฝ๋กœ์—ฌ๋„ ๊ฐ€์ค‘์น˜ ํ•ฉ์ด ์ตœ์†Œ์ด๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค๋ฉด ๋‹ค์ต์ŠคํŠธ๋ผ๋ฅผ ์‚ฌ์šฉ
    • BFS์—์„œ๋Š” ๊ฐ€์ค‘์น˜๊ฐ€ ์—†๊ฑฐ๋‚˜ ๋™์ผํ•œ ๋ฐ˜๋ฉด, ๋‹ค์ต์ŠคํŠธ๋ผ์—์„œ๋Š” ๊ฐ€์ค‘์น˜๊ฐ€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค.
    • BFS์—์„œ๋Š” Queue๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ˜๋ฉด, ๋‹ค์ต์ŠคํŠธ๋ผ์—์„œ๋Š” Priority Queue ๋˜๋Š” Heap์„ ์‚ฌ์šฉํ•œ๋‹ค.
    • ํ˜„์žฌ ๋…ธ๋“œ์˜ ์ธ์ ‘ ๋…ธ๋“œ๋“ค์„ ํƒ์ƒ‰ํ•  ๋•Œ, BFS์—์„œ๋Š” ๋ฐฉ๋ฌธํ•œ ์ ์ด ์—†๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฐ˜๋ฉด, ๋‹ค์ต์ŠคํŠธ๋ผ์—์„œ๋Š” ์ตœ์†Œ ๊ฑฐ๋ฆฌ์ธ์ง€ ํ™•์ธํ•œ๋‹ค.

๋ฒจ๋งŒ-ํฌ๋“œ (Bellman-ford) ์•Œ๊ณ ๋ฆฌ์ฆ˜

: ํŠน์ • ๋…ธ๋“œ์—์„œ ๋‹ค๋ฅธ ๋ชจ๋“  ๋…ธ๋“œ๋“ค๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•  ๋•Œ ์‚ฌ์šฉ (์Œ์ˆ˜ ๊ฑฐ๋ฆฌ๊ฐ€ ์žˆ์„ ๋•Œ!)

  • ํŠน์ง•

    • ๋…ธ๋“œ ๊ฐ„ ๊ฑฐ๋ฆฌ๊ฐ€ ์ฃผ์–ด์ง€๋Š” ๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„์—ฌ์•ผ ํ•จ
    • ๊ฑฐ๋ฆฌ๊ฐ€ ์Œ์ˆ˜์—ฌ๋„ ๋จ
    • ๋…ธ๋“œ๊ฐ€ n๊ฐœ์ผ ๋•Œ ์—ฃ์ง€์˜ ์ตœ๋Œ€ ๊ฐฏ์ˆ˜๋Š” (n-1)์ด๋ฏ€๋กœ ๊ฑฐ๋ฆฌ ์—…๋ฐ์ดํŠธ๋ฅผ (n-1)๋ฒˆ ๋ฐ˜๋ณต
  • ์‹œ๊ฐ„๋ณต์žก๋„: O(VE)

  • ์ฝ”๋”ฉํ…Œ์ŠคํŠธ์—์„œ๋Š” ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ๋ณด๋‹ค ์Œ์ˆ˜ ์‚ฌ์ดํด์„ ํŒ๋ณ„ํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋” ๋งŽ์ด ์ถœ์ œ๋จ

  • ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

    1. ๊ทธ๋ž˜ํ”„๋ฅผ ์—ฃ์ง€ ๋ฆฌ์ŠคํŠธ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค.
      • ์—ฃ์ง€ ๋ฆฌ์ŠคํŠธ์˜ ๊ฐ ์ธ๋ฑ์Šค๋งˆ๋‹ค (๋…ธ๋“œ1, ๋…ธ๋“œ2, ๊ฐ€์ค‘์น˜)๊ฐ€ ์ €์žฅ๋จ
    2. distance ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค๊ณ , ์ถœ๋ฐœ ๋…ธ๋“œ์˜ ๊ฑฐ๋ฆฌ๋Š” 0, ๋‹ค๋ฅธ ๋…ธ๋“œ๋“ค์˜ ๊ฑฐ๋ฆฌ๋Š” INF๋กœ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.
    3. ๊ฑฐ๋ฆฌ ์—…๋ฐ์ดํŠธ๋ฅผ (n-1)๋ฒˆ ๋ฐ˜๋ณตํ•œ๋‹ค.
      • distance[src_node] == INF์ผ ๋•Œ, ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•˜์ง€ X
      • distance[src_node] + weight < distance[tgt_node]์ผ ๋•Œ, distance[tgt_node]๋ฅผ ์—…๋ฐ์ดํŠธ
    4. ์Œ์ˆ˜ ์‚ฌ์ดํด์ด ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
      • ๋ชจ๋“  ์—ฃ์ง€๋ฅผ ํ•œ๋ฒˆ์”ฉ ๋‹ค์‹œ ์‚ฌ์šฉํ•ด ์—…๋ฐ์ดํŠธ๋œ ๋…ธ๋“œ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ
      • ์—…๋ฐ์ดํŠธ๊ฐ€ ์ผ์–ด๋‚ฌ์œผ๋ฉด ์Œ์ˆ˜ ์‚ฌ์ดํด์ด ์กด์žฌํ•˜๋Š” ๊ฒƒ => ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ์ฐพ์„ ์ˆ˜ ์—†์Œ
    # ๊ทธ๋ž˜ํ”„๋ฅผ ์—ฃ์ง€ ๋ฆฌ์ŠคํŠธ๋กœ ๊ตฌํ˜„
    graph = []
    for _ in range(m):
        src_node, tgt_node, dist = map(int, input().split())
        graph.append((src_node, tgt_node, dist))
        
    # distance ๋ฆฌ์ŠคํŠธ ๋งŒ๋“ค๊ธฐ
    INF = 10 ** 6
    distance = [INF] * (n+1)
    
    # start ๋…ธ๋“œ
    start = 1
    distance[start] = 0
    
    # ๋ฒจ๋งŒ-ํฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜
    for _ in range(n-1):    # (n-1)๋ฒˆ ๋ฐ˜๋ณต
        for (src_node, tgt_node, dist) in graph:
            if distance[src_node] != INF and distance[src_node] + dist < distance[tgt_node]:
                distance[tgt_node] = distance[src_node] + dist
    # ์Œ์ˆ˜ ์‚ฌ์ดํด ํŒ๋ณ„
    neg_cycle = False
    for (src_node, tgt_node, dist) in graph:    # 1๋ฒˆ ๋ฐ˜๋ณต
        if distance[src_node] != INF and distance[src_node] + dist < distance[tgt_node]:
            # ์—…๋ฐ์ดํŠธ๊ฐ€ ์ผ์–ด๋‚˜๋Š” ๊ฒฝ์šฐ (์Œ์ˆ˜ ์‚ฌ์ดํด ์กด์žฌ)
            neg_cycle = True
            break

ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ (Floyd-warshall) ์•Œ๊ณ ๋ฆฌ์ฆ˜

: ๋ชจ๋“  ๋…ธ๋“œ ๊ฐ„์— ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•  ๋•Œ ์‚ฌ์šฉ

  • ํŠน์ง•

    • ๋…ธ๋“œ ๊ฐ„ ๊ฑฐ๋ฆฌ๊ฐ€ ์ฃผ์–ด์ง€๋Š” ๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„์—ฌ์•ผ ํ•จ
    • ๊ฑฐ๋ฆฌ๊ฐ€ ์Œ์ˆ˜์—ฌ๋„ ๋จ
    • Dynamic Programming์˜ ์›๋ฆฌ๋ฅผ ์ด์šฉ
      • A โ†’ B ๋กœ ๊ฐ€๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ–ˆ์„ ๋•Œ, ๊ทธ ๊ฒฝ๋กœ ์œ„์— ์กด์žฌํ•˜๋Š” C ๋…ธ๋“œ์— ๋Œ€ํ•ด A โ†’ C, C โ†’ B ๊ฒฝ๋กœ ์—ญ์‹œ ์ตœ๋‹จ ๊ฒฝ๋กœ์ž„
  • ์‹œ๊ฐ„๋ณต์žก๋„: O(V^3)

    • ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ ๋†’๊ธฐ ๋•Œ๋ฌธ์— ๋…ธ๋“œ ์ˆ˜๋Š” ์ ๊ฒŒ ์ฃผ์–ด์ง
  • ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

    1. distance ๋ฆฌ์ŠคํŠธ๋ฅผ ์ด์ฐจ์›์œผ๋กœ ๋งŒ๋“ค๊ณ , ์ž๊ธฐ ์ž์‹ ์„ ๋œปํ•˜๋Š” ๋Œ€๊ฐ์„  ์นธ์˜ ๊ฑฐ๋ฆฌ๋Š” 0, ๋‹ค๋ฅธ ์นธ์˜ ๊ฑฐ๋ฆฌ๋Š” INF๋กœ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.
    2. ๊ทธ๋ž˜ํ”„์˜ ๋ฐ์ดํ„ฐ๋ฅผ distance ๋ฆฌ์ŠคํŠธ์— ์ €์žฅํ•œ๋‹ค.
    3. 3์ค‘ for๋ฌธ์œผ๋กœ ์ ํ™”์‹์— ๋”ฐ๋ผ ๊ฑฐ๋ฆฌ๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.
      • for๋ฌธ ์ˆœ์„œ: ๊ฒฝ์œ  ๋…ธ๋“œ K์— ๋Œ€ํ•ด โ†’ ์ถœ๋ฐœ ๋…ธ๋“œ S์— ๋Œ€ํ•ด โ†’ ๋„์ฐฉ ๋…ธ๋“œ E์— ๋Œ€ํ•ด
      • ์ ํ™”์‹: distance[S][E] = min(distance[S][E], distance[S][K] + distance[K][E])
    # distance ๋ฆฌ์ŠคํŠธ ๋งŒ๋“ค๊ธฐ
    INF = 10 ** 6
    distance = [[INF] * (n+1) for _ in range(n+1)]
    for i in range(1, n+1):
        distance[i][i] = 0
    
    # ๊ทธ๋ž˜ํ”„์˜ ๋ฐ์ดํ„ฐ๋ฅผ distance ๋ฆฌ์ŠคํŠธ์— ์ €์žฅํ•˜๊ธฐ
    for _ in range(m):
        s, e, dist = map(int, input().split())
        if distance[s][e] > dist:
            distance[s][e] = dist
    
    # ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ ์•Œ๊ณ ๋ฆฌ์ฆ˜
    # 3์ค‘ for๋ฌธ์œผ๋กœ ๊ฑฐ๋ฆฌ ์—…๋ฐ์ดํŠธ
    for k in range(1, n+1):
        for i in range(1, n+1):
            for j in range(1, n+1):
                if distance[i][j] > distance[i][k] + distance[k][j]:    # ์ ํ™”์‹
                    distance[i][j] = distance[i][k] + distance[k][j]

์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ (minimum spanning tree)

: ๊ทธ๋ž˜ํ”„์—์„œ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ์—ฐ๊ฒฐํ•  ๋•Œ ์‚ฌ์šฉ๋œ ์—์ง€๋“ค์˜ ๊ฐ€์ค‘์น˜ ํ•ฉ์„ ์ตœ์†Œ๋กœ ํ•˜๋Š” ํŠธ๋ฆฌ

  • ํŠน์ง•

    • ์‚ฌ์ดํด์ด ์ƒ๊ธฐ์ง€ ์•Š๋„๋ก ์—ฐ๊ฒฐํ•จ
    • ๋…ธ๋“œ๊ฐ€ n๊ฐœ์ด๋ฉด ์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ์—์ง€๋Š” ํ•ญ์ƒ (n-1)๊ฐœ
    • ์œ ๋‹ˆ์˜จ ํŒŒ์ธ๋“œ๋ฅผ ํ™œ์šฉํ•ด ๊ตฌํ˜„
  • ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

    1. ๊ทธ๋ž˜ํ”„๋ฅผ ์—ฃ์ง€ ๋ฆฌ์ŠคํŠธ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค. ์œ ๋‹ˆ์˜จ ํŒŒ์ธ๋“œ ๋ฆฌ์ŠคํŠธ๋„ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.
      • ์—ฃ์ง€ ๋ฆฌ์ŠคํŠธ์˜ ๊ฐ ์ธ๋ฑ์Šค๋งˆ๋‹ค (๋…ธ๋“œ1, ๋…ธ๋“œ2, ๊ฐ€์ค‘์น˜)๊ฐ€ ์ €์žฅ๋จ
    2. ์—ฃ์ง€ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ€์ค‘์น˜ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค.
      • ์ด๋ฅผ ์œ„ํ•ด ์—ฃ์ง€ ๋ฆฌ์ŠคํŠธ๋ฅผ ์šฐ์„ ์ˆœ์œ„ ํ๋กœ ๊ตฌํ˜„
    3. ๊ฐ€์ค‘์น˜๊ฐ€ ๋‚ฎ์€ ์—ฃ์ง€๋ถ€ํ„ฐ ์ˆœ์„œ๋Œ€๋กœ ์„ ํƒํ•ด, ์‚ฌ์ดํด์ด ํ˜•์„ฑ๋˜์ง€ ์•Š๋Š”์ง€ ํ™•์ธ ํ›„ ๋‘ ๋…ธ๋“œ๋ฅผ ์—ฐ๊ฒฐํ•œ๋‹ค.
      • ์‚ฌ์ดํด ํ˜•์„ฑ ํ™•์ธ: find ์—ฐ์‚ฐ
      • ๋‘ ๋…ธ๋“œ๋ฅผ ์—ฐ๊ฒฐ: union ์—ฐ์‚ฐ
    4. ์—ฐ๊ฒฐ๋œ ์—ฃ์ง€๊ฐ€ (n-1)๊ฐœ๊ฐ€ ๋  ๋•Œ๊นŒ์ง€ 3๋ฒˆ ์ž‘์—…์„ ๋ฐ˜๋ณตํ•œ๋‹ค.
    from queue import PriorityQueue
    import sys
    input = sys.stdin.readline
    
    V, E = map(int, input().split())
    queue = PriorityQueue()
    for _ in range(E):
        node1, node2, weight = map(int, input().split())
        queue.put((weight, node1, node2))  # weight ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌ
    parents = list(range(V + 1))
    
    
    def find(node):
        if node == parents[node]:
            return node
        else:
            parent_node = find(parents[node])
            parents[node] = parent_node
            return parent_node
    
    def union(node1, node2):
        node1_parent = find(node1)
        node2_parent = find(node2)
        if node1_parent <= node2_parent:
            parents[node2_parent] = node1_parent
        else:
            parents[node1_parent] = node2_parent
    
    
    weight_sum, edge_cnt = 0, 0
    while queue.qsize() > 0 and edge_cnt < V-1:
        weight, node1, node2 = queue.get()
    
        # ์‚ฌ์ดํด ํ˜•์„ฑ ์—ฌ๋ถ€ ํ™•์ธ
        node1_parent, node2_parent = find(node1), find(node2)
        if node1_parent == node2_parent:  # ์—ฐ๊ฒฐ X
            continue
    
        # ๋‘ ๋…ธ๋“œ ์—ฐ๊ฒฐ
        union(node1, node2)
        weight_sum += weight
        edge_cnt += 1
    
    print(weight_sum)

์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ (Segment Tree)

: ๋ฐ์ดํ„ฐ์˜ ํŠน์ • ๊ตฌ๊ฐ„ ํ•ฉ๊ณผ ์—…๋ฐ์ดํŠธ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ

  • ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ์˜ ์ข…๋ฅ˜: ๊ตฌ๊ฐ„ ํ•ฉ, ์ตœ๋Œ€๊ฐ’, ์ตœ์†Œ๊ฐ’

  • ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ ๋งŒ๋“ค๊ธฐ

    • ๋ฐ์ดํ„ฐ๊ฐ€ $N$๊ฐœ์ผ ๋•Œ, $2^k &gt;= N$ ์„ ๋งŒ์กฑํ•˜๋Š” ์ตœ์†Œ์˜ $k$๋ฅผ ๊ตฌํ•œ ํ›„, $2^{k+1}$ ํฌ๊ธฐ์˜ ํŠธ๋ฆฌ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ฆ
    • ํŠธ๋ฆฌ ๋ฆฌ์ŠคํŠธ์˜ $2^k$ index๋ถ€ํ„ฐ ์ฃผ์–ด์ง„ ๋ฐ์ดํ„ฐ $N$๊ฐœ๋ฅผ ์ฑ„์›€ (Leaf ๋…ธ๋“œ)
    • ์ฑ„์›Œ์ง„ ๊ฐ’์„ ์ด์šฉํ•ด ๋ถ€๋ชจ ๋…ธ๋“œ๋กœ ์˜ฌ๋ผ๊ฐ€๋ฉด์„œ ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ์˜ ์ข…๋ฅ˜์— ๋”ฐ๋ผ ๊ฐ’์„ ์ฑ„์›€
      • ๊ตฌ๊ฐ„ ํ•ฉ: tree[i] = tree[2i] + tree[2i+1]
      • ์ตœ๋Œ€๊ฐ’: tree[i] = max(tree[2i], tree[2i+1])
      • ์ตœ์†Œ๊ฐ’: tree[i] = min(tree[2i], tree[2i+1])
  • ๊ตฌ๊ฐ„ ํ•ฉ/์ตœ๋Œ€๊ฐ’/์ตœ์†Œ๊ฐ’ ๊ตฌํ•˜๊ธฐ

    • ์ฃผ์–ด์ง„ ์งˆ์˜ index๋ฅผ ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ์˜ Leaf ๋…ธ๋“œ์— ํ•ด๋‹นํ•˜๋Š” index๋กœ ๋ณ€๊ฒฝ
      • ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ index = ์งˆ์˜ index + ($2^k - 1$)
    • ๋‹ค์Œ์˜ ๊ณผ์ •์„ ๊ฑฐ์นจ
      1. start_index % 2 == 1์ด๋ฉด ํ•ด๋‹น ๋…ธ๋“œ๋ฅผ ์„ ํƒํ•ด ์—ฐ์‚ฐ ์ˆ˜ํ–‰
        • start_index += 1
      2. end_index % 2 == 0์ด๋ฉด ํ•ด๋‹น ๋…ธ๋“œ๋ฅผ ์„ ํƒํ•ด ์—ฐ์‚ฐ ์ˆ˜ํ–‰
        • end_index -= 1
      3. start_index์˜ depth ๋ณ€๊ฒฝ: start_index = start_index // 2
      4. end_index์˜ depth ๋ณ€๊ฒฝ: end_index = end_index // 2
      • a~d ์ž‘์—…์„ ๋ฐ˜๋ณตํ•˜๋‹ค๊ฐ€ start_index > end_index๊ฐ€ ๋˜๋ฉด ์ข…๋ฃŒ
  • ๊ฐ’ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ

    • ์—…๋ฐ์ดํŠธ๋œ ๋…ธ๋“œ์˜ ๊ฐ’๊ณผ ๋ถ€๋ชจ๊ฐ€ ๊ฐ™์€ ๋‹ค๋ฅธ ์ž์‹ ๋…ธ๋“œ์˜ ๊ฐ’์— ๋Œ€ํ•ด ์—ฐ์‚ฐํ•˜๊ณ  ๊ณ„์†ํ•ด์„œ ๋ถ€๋ชจ ๋…ธ๋“œ๋กœ ์˜ฌ๋ผ๊ฐ
    • ์—…๋ฐ์ดํŠธ๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š์œผ๋ฉด ์ข…๋ฃŒ
    • ex) ์ตœ๋Œ€๊ฐ’ ํŠธ๋ฆฌ์—์„œ, 6๋ฒˆ ๋…ธ๋“œ์˜ ๊ฐ’์ด ์—…๋ฐ์ดํŠธ๋จ โ†’ 6๋ฒˆ๊ณผ 7๋ฒˆ ๋…ธ๋“œ์˜ ๊ฐ’ ์ค‘ ๋” ํฐ ๊ฐ’์„ ๋ถ€๋ชจ์ธ 3๋ฒˆ ๋…ธ๋“œ์— ์—…๋ฐ์ดํŠธ โ†’ 3๋ฒˆ ๋…ธ๋“œ์™€ 2๋ฒˆ ๋…ธ๋“œ ๊ฐ’ ๋น„๊ตํ•ด์„œ ๋” ํฐ ๊ฐ’์„ ๋ถ€๋ชจ์ธ 1๋ฒˆ ๋…ธ๋“œ์— ์—…๋ฐ์ดํŠธ
  • ์ฝ”๋“œ

    # 2^k>=N ๋งŒ์กฑํ•˜๋Š” k ๊ตฌํ•˜๊ธฐ
    length = N
    k = 0
    while length != 0:
        length = length // 2
        k += 1
    # N: 5, k = 0
    # N: 2, k = 1
    # N: 1, k = 2
    # N: 0, k = 3
    
    # 2^(k+1) ํฌ๊ธฐ์˜ ๋ฆฌ์ŠคํŠธ ๋งŒ๋“ค๊ธฐ
    # ์ตœ์†Œ๊ฐ’ ํŠธ๋ฆฌ์—์„œ๋Š” INF๋กœ ์ดˆ๊ธฐํ™”, ๊ตฌ๊ฐ„ํ•ฉ/์ตœ๋Œ€๊ฐ’ ํŠธ๋ฆฌ์—์„œ๋Š” 0์œผ๋กœ ์ดˆ๊ธฐํ™”
    INF = 10 ** 6
    tree_size = 2 ** (k+1)
    tree = [INF] * (tree_size + 1)  # [0]์€ ์‚ฌ์šฉ X
    
    # 2^k index๋ถ€ํ„ฐ ์ฃผ์–ด์ง„ ๋ฐ์ดํ„ฐ ์ €์žฅ
    for i in range(2**k, 2**k + N):
        tree[i] = int(input())  # ๋ฐ์ดํ„ฐ ์ž…๋ ฅ
    
    # ๋ถ€๋ชจ ๋…ธ๋“œ๋กœ ์˜ฌ๋ผ๊ฐ€๋ฉด์„œ ๊ฐ’ ์ฑ„์šฐ๊ธฐ
    i = tree_size
    while i != 1:   # 1์ด๋ฉด Root ๋…ธ๋“œ์ด๋ฏ€๋กœ ์ข…๋ฃŒ
        if tree[i//2] > tree[i]:
            tree[i//2] = tree[i]
        i -= 1
        
    
    # a๋ฒˆ์งธ๋ถ€ํ„ฐ b๋ฒˆ์งธ ๊ฐ’ ์ค‘์—์„œ ์ตœ์†Œ๊ฐ’ ๊ตฌํ•˜๊ธฐ
    start, end = a + (2**k - 1), b + (2**k - 1) # ์งˆ์˜ index๋ฅผ ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ์˜ index๋กœ ๋ณ€๊ฒฝ
    selected_nums = []
    while start <= end:
        if start % 2 == 1:
            selected_nums.append(tree[start])
            start += 1
        if end % 2 == 0:
            selected_nums.append(tree[end])
            end -= 1
        start = start // 2
        end = end // 2
    
    answer = sum(selected_nums)
    answer = max(selected_nums)
    answer = min(selected_nums)

์ˆœ์—ด
  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ™œ์šฉ ์ฝ”๋“œ

    from itertools import permutations
    
    li1 = [1,2,3,4]
    
    permutations(li1)       # 4!
    permutations(li1, r=2)  # 4P2
    • ๊ฒฐ๊ณผ๋กœ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ list()๋ฅผ ์”Œ์›Œ์ฃผ์ž. ๋‚ด๋ถ€ ๊ฐ’๋“ค์€ ํŠœํ”Œ ํ˜•ํƒœ์ด๋‹ค.
  • n๊ฐœ์˜ ์ˆ˜๋กœ ์ˆœ์—ด์„ ๋งŒ๋“œ๋Š” ์ƒํ™ฉ์—์„œ, ๋‹ค์Œ์„ ์ด์šฉํ•˜์ž.

    • 1๋ฒˆ์งธ ์ž๋ฆฟ์ˆ˜๊ฐ€ ์ •ํ•ด์กŒ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์„ ๋•Œ, ๊ทธ ๋‹ค์Œ์— ์˜ฌ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋Š” (n-1)!์ด๋‹ค.
    • 2๋ฒˆ์งธ ์ž๋ฆฟ์ˆ˜๊ฐ€ ์ •ํ•ด์กŒ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์„ ๋•Œ, ๊ทธ ๋‹ค์Œ์— ์˜ฌ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋Š” (n-2)!์ด๋‹ค.
    • ...
    • ์ฐธ๊ณ  ๋ธ”๋กœ๊ทธ

๋™์  ๊ณ„ํš๋ฒ• (Dynamic Programming)

: ๋ณต์žกํ•œ ๋ฌธ์ œ๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฐ„๋‹จํ•œ ๋ฌธ์ œ๋กœ ๋ถ„๋ฆฌํ•˜๊ณ , ๋ถ€๋ถ„ ๋ฌธ์ œ๋“ค์„ ํ•ด๊ฒฐํ•จ์œผ๋กœ์จ ์ตœ์ข…์ ์ธ ๋ฌธ์ œ์˜ ๋‹ต์„ ๊ตฌํ•˜๋Š” ๋ฐฉ๋ฒ•

  • ํฐ ๋ฌธ์ œ๋ฅผ ์ž‘์€ ๋ฌธ์ œ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์–ด์•ผํ•จ

  • ์ž‘์€ ๋ฌธ์ œ๋“ค์ด ๋ฐ˜๋ณต์ ์œผ๋กœ ๋‚˜ํƒ€๋‚˜๊ณ  ์‚ฌ์šฉ๋˜๋ฉฐ, ์ด ๊ฒฐ๊ณผ๊ฐ’์€ ํ•ญ์ƒ ๊ฐ™์•„์•ผํ•จ

  • ๋ชจ๋“  ์ž‘์€ ๋ฌธ์ œ์˜ ๊ฒฐ๊ณผ๊ฐ’์€ ํ•œ๋ฒˆ๋งŒ ๊ณ„์‚ฐํ•˜์—ฌ DP ํ…Œ์ด๋ธ”์— ์ €์žฅ (Memoization)

  • Top-down ๋ฐฉ์‹ ๋˜๋Š” Bottom-up ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Œ

    • Top-down ๋ฐฉ์‹: ์ฃผ๋กœ ์žฌ๊ท€ํ•จ์ˆ˜ ์‚ฌ์šฉ
    • Bottom-up ๋ฐฉ์‹: ์ฃผ๋กœ ๋ฐ˜๋ณต๋ฌธ ์‚ฌ์šฉ
  • ๋™์  ๊ณ„ํš๋ฒ•์œผ๋กœ ํ’€ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํŒ๋‹จํ–ˆ์œผ๋ฉด ์ ํ™”์‹ ์„ธ์šฐ๊ธฐ

  • ๋Œ€ํ‘œ์ ์ธ ๋ฌธ์ œ

About

Practice for algorithm coding tests.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages