스파르타코딩 - 알고리즘 강의 2 주차

코일·2021년 11월 19일
0
post-thumbnail
  • 링크드리스트
    class Node:
        def __init__(self, data):
            self.data = data
            self.next = None
    
    class LinkedList:
        def __init__(self, value):  # 초기값
            self.head = Node(value)  
    
        def append(self, value):
            cur = self.head
            while cur.next is not None:  # None 이 되지 않는 동안.
                cur = cur.next
            cur.next = Node(value)
    
        def print_all(self):
            cur = self.head
            while cur is not None:
                print(cur.data)
                cur = cur.next
    
        def get_node(self, index):
            node = self.head
            count = 0
            while count < index:
                node = node.next
                count += 1
            return node
    
        def add_node(self, index, value):
            new_node = Node(value)  # 새로운 노드에 값을 입력값을 넣음
    
            if index == 0:  # 0일 경우를 생각
                new_node.next = self.head  # 새노드의 다음것에 기존의 헤드를 주고
                self.head = new_node  # 진짜 헤드는 새노드가 가져간다.
                return
    
            node = self.get_node(index - 1)  # get_node 함수데려옴
            next_node = node.next
            node.next = new_node
            new_node.next = next_node
    
        def delete_node(self, index):
            if index == 0:
                self.head = self.head.next
                return
    
            node = self.get_node(index - 1)
            node.next = node.next.next
    
    linked_list = LinkedList(5)
    linked_list.append(12)
    linked_list.add_node(0, 3)
    linked_list.print_all()
    linked_list.delete_node(0)
    print('------')
    linked_list.print_all()
  • 링크드리스트 - 각 자리수 더하기
    class Node:
        def __init__(self, data):
            self.data = data
            self.next = None
    
    class LinkedList:
        def __init__(self, value):
            self.head = Node(value)
    
        def append(self, value):
            cur = self.head
            while cur.next is not None:
                cur = cur.next
            cur.next = Node(value)
    
    def get_linked_list_sum(linked_list_1, linked_list_2):
        sum_1 = _get_linked_list_sum(linked_list_1)
        sum_2 = _get_linked_list_sum(linked_list_2)
    
        return sum_1 + sum_2
    
        # sum_1 = 0
        # head_1 = linked_list_1.head
        # while head_1 is not None:
        #     sum_1 = sum_1 * 10 + head_1.data
        #     head_1 = head_1.next
        #
        # sum_2 = 0
        # head_2 = linked_list_2.head
        # while head_2 is not None:
        #     sum_2 = sum_2 * 10 + head_2.data
        #     head_2 = head_2.next
        #
        # return sum_1 + sum_2
    
        # 좋은 코드는 최소한의 반복
    
    def _get_linked_list_sum(linked_list):
        linked_list_sum = 0
        head = linked_list.head
        while head is not None:
            linked_list_sum = linked_list_sum * 10 + head.data  # *
            head = head.next
    
        return linked_list_sum
    
    linked_list_1 = LinkedList(6)
    linked_list_1.append(7)
    linked_list_1.append(8)
    
    linked_list_2 = LinkedList(3)
    linked_list_2.append(5)
    linked_list_2.append(4)
    
    print(get_linked_list_sum(linked_list_1, linked_list_2))
  • 이진 탐색
    finding_target = 14
    finding_numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    
    # 이진 탐색
    # 분석
    # 0. 이진 탐색은 정렬이 필요함을 인지.
    # 1. 탐색할 길이(배열)을 정함 (최소값, 최대값)
    # 2. 길이를 나눔 (나눈값)
    # 3. 나누었을때 나눈값이 target 이면 True
    # 4. 나누었을때 나눈값이 target 보다 크면 최소값이 나눈값으로
    # 5. 나누었을때 나눈값이 target 보다 작으면 최대값이 나눈값으로
    # 6. break Point 는 최소값과 최대값이 같을때,(크거나 같을때)
    # 7. target 이 없으면 False
    
    def is_existing_target_number_binary(target, array):
    
        current_min = 0  # 최소값의 초기값
        current_max = len(array) - 1  # 최대값의 초기값 ( array 의 맨 마지막 자리 : len(array) -1
        current_guess = (current_min + current_max) // 2  # 반으로 나누었을 때 나머지는 탈락
    
        while current_min <= current_max:  # 최소값이 최대값보다 같거나 커질때 까지 반복
            if array[current_guess] == target:  # 입력받은 target 값 과 나눈값이 같다면 True 반환
                return True
            elif array[current_guess] < target:  # 나눈값 보다 target 값이 크다면
                current_min = current_guess + 1  # target 값 다음 값을 최소값으로 함
            else:
                current_max = current_guess - 1  # 그게아니면, 최대값을 나눈값(-1)으로 함
            current_guess = (current_min + current_max) // 2  # if 문에 걸리지 않으면 다시 나누어줌
    
        return False  # 찾지못했을때 반환
    
    result = is_existing_target_number_binary(finding_target, finding_numbers)
    print(result)
  • 재귀 - 카운트다운
    def count_down(number):
        if number < 0:
            return
        print(number)           # number 를 출력하고
        count_down(number - 1)  # count_down 함수를 number - 1 인자를 주고 다시 호출한다!
    
    count_down(60)
  • 재귀 - 팩토리얼
    # 팩토리얼 : 1 * 2 * 3 * 4 ...
    
    def factorial(n):
        if n == 0:
            return 1
        print(n)
        return n * factorial(n - 1)
    
    print(factorial(5))
  • 재귀 - 팔린드롬 ( 회문 )
    input = "abcba"
    
    def is_palindrome(string):
        print(string)
        if len(string) <= 1:  # 문자길이보다 1이 크거나 같으면 (문자가 다 회문한것이기 때문에)
            return True
        if string[0] != string[-1]:  # 0번째 와 -1 번째(맨끝값) 가 같지 않으면
            return False
    
        return is_palindrome(string[1:-1])  # 1번째 부터 -1 이전까지 (slice의 특징)
    
    print(is_palindrome(input))
  • HW - -k 번째 찾기
    class Node:
        def __init__(self, data):
            self.data = data
            self.next = None
    
    class LinkedList:
        def __init__(self, value):
            self.head = Node(value)
    
        def append(self, value):
            cur = self.head
            while cur.next is not None:
                cur = cur.next
            cur.next = Node(value)
    
        def get_kth_node_from_last(self, k):
            length = 1
            cur = self.head
    
            # 카운트 세면서 끝까지 가봄
            while cur.next is not None: 
                cur = cur.next
                length += 1 # 범위를 가져놓자
            
            # 끝에서 - k 하고,
            # 다시 처음부터 해야하니까 cur을 초기화해줌
            end_length = length - k
            cur = self.head
            
            # end_length 만큼 또 cur.next를 한다.
            for i in range(end_length):
                cur = cur.next
    
            return cur # 출력
    
    linked_list = LinkedList(6)
    linked_list.append(7)
    linked_list.append(8)
    linked_list.append(9)
    linked_list.append(10)
    linked_list.append(11)
    
    print(linked_list.get_kth_node_from_last(2).data)  # 10이 나와야 합니다!
  • HW - 배달의 민족 배달 가능 여부
    shop_menus = ["만두", "떡볶이", "오뎅", "사이다", "콜라"]
    shop_orders = ["오뎅", "콜라", "만두"]
    
    def is_available_to_order(menus, orders):
        menus_set = set(menus)
    
        for order in orders:
            if order not in menus_set:
                return False
    
        return True
    
    result = is_available_to_order(shop_menus, shop_orders)
    print(result)
  • HW - 더하거나 빼거나
    numbers = [2, 3, 1]
    target_number = 0
    result_count = 0  # target 을 달성할 수 있는 모든 방법의 수를 담기 위한 변수
    
    def get_count_of_ways_to_target_by_doing_plus_or_minus(array, target, current_index, current_sum):
        if current_index == len(array):  # 탈출조건!
            if current_sum == target:
                global result_count
                result_count += 1  # 마지막 다다랐을 때 합계를 추가해주면 됩니다.
            return
        get_count_of_ways_to_target_by_doing_plus_or_minus(array, target, current_index + 1,
                                                           current_sum + array[current_index])
        get_count_of_ways_to_target_by_doing_plus_or_minus(array, target, current_index + 1,
                                                           current_sum - array[current_index])
    
    get_count_of_ways_to_target_by_doing_plus_or_minus(numbers, target_number, 0, 0)
    # current_index 와 current_sum 에 0, 0을 넣은 이유는 시작하는 총액이 0, 시작 인덱스도 0이니까 그렇습니다!
    print(result_count)  # 2가 반환됩니다!
profile
How do you get what you want?🤔🤔

0개의 댓글