0401 TIL

looggi·2023년 3월 31일
0

TILs

목록 보기
52/114
post-thumbnail

DevOps란

서비스 개발 방법론
개발(Development)+ 운영(Operations)
소프트웨어 개발자와 정보기술 전문가 사이의 소통, 협업 및 통합을 강조하는 개발 환경이나 문화
데브옵스(DevOps)는 개발(Dev)과 운영(Ops)을 분리해왔던 기존의 '소프트웨어 개발 생명주기(Software Development Life Cycle, SDLC)' 방법론을 뛰어넘을 수 있게 해줄 것으로 기대
소프트웨어 배포의 속도와 질을 향상시키는 것을 목표로함

리코드 문제풀기

21. Merge Two Sorted Lists

class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        list3=ListNode()
        cur=list3
        while list1 or list2:
            if list1 and list2:
                if list1.val<=list2.val:
                    cur.next=ListNode(list1.val)
                    list1=list1.next
                else:
                    cur.next=ListNode(list2.val)
                    list2=list2.next
            elif not list1:
                cur.next=ListNode(list2.val)
                list2=list2.next
            elif not list2:
                cur.next=ListNode(list1.val)
                list1=list1.next
            cur=cur.next
        return list3.next

링크드리스트를 까먹기전에 한번 더 풀어보고 싶어서 풀었는데
음 if문에서 왜 오류가 났는지 모르겠다
그래서 일단은 통과시키기위해서 겁나 길게 풀어써버렸는데 if not list2 and list1.val<=list2.val 이런식으로 조건문을 쓰면 NoneType은 val이라는 어트리뷰트가 없다고 타입에러가 난다.. 나도 아는데..

내가 쓴 로직은 list1과 list2의 각 노드를 비교해서 작은 걸 list3의 다음 노드로 만들어준 것이다.

다른 사람 풀이 구경

class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        cur = dummy = ListNode()
        while list1 and list2:               
            if list1.val < list2.val:
                cur.next = list1
                list1, cur = list1.next, list1
            else:
                cur.next = list2
                list2, cur = list2.next, list2
                
        if list1 or list2:
            cur.next = list1 if list1 else list2
            
        return dummy.next

우선 cur=dummy=ListNode()로 한줄로 줄여 써줄 수 있다
이 사람은 아예 두 리스트 모두 값이 있을 때에만 비교를 통해 붙여줬고
나머지는 그냥 둘중에 하나만 있다면 하나만 쭉 이어붙여주도록 했다
어차피 애초에 둘다 sorted이기도 하고 둘 모두 값이 존재할 동안엔 값을 비교해서 넣어줬기때문에 마지막에 if문을 통해 이어붙여주는 list의 시작값이 while문에서 마지막으로 붙은 노드 값보다 작을 수는 없다.

헐 그리고 굳이 ListNode(list1.val)이렇게 할 필요가 없다.. 얘네 이미 리스트노든데 굳이!!!😒
cur.next=list1 이렇게 하는 것만으로도 충분하다..

깔끔하당.. 담엔 나도 이렇게 풀어야지

근데 얘네 주르륵 다 넣어주는건가..? 저렇게 주르륵 들어갈 수 있으면..? 주르륵이라고 볼 수 있지만 주르륵이라기보단 헤드의 위치니까.. 무튼 주르륵 넣을 수도 있단 게 중요한거지

without dummy

class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        if not list1 and not list2:
            return list1
        if not list1 or not list2:
            return list1 if not list2 else list2
        seek, target = (list1, list2) if list1.val < list2.val else (list2, list1)
        head = seek
        while seek and target:
            while seek.next and seek.next.val < target.val:
                seek = seek.next
            seek.next, target = target, seek.next
            seek = seek.next
        return head

첫번째 if문은 list1과 list2가 모두 none일 때 예외처리
두번째 if문은 list1또는 list2가 none일 때 예외처리
이후가 진짜 로직이라고 볼 수 있는데 seek, target변수에 작은 값, 큰 값 순으로 리스트노드를 넣어주고 작은 값을 헤드로 정해준다
seek과 target이 모두 none이 아닐 때
내부 while문에서 작은값seek이 none이 아니면서 target값보다 작을 때 seek에 그 다음 노드를 넣어준다
while문을 탈출했다면 target값보다 크거나 seek이 none인 경우이므로 seek과 target의 값을 바꿔줘서 다음 내부while문에서는 none이 아니거나 더 작은 값의 노드가 붙을 수 있도록 해준다
이후 seek은 당연히 seek.next값을 넣어줘서 헤드의 위치를 이동시켜준다

값은 ListNode.val로 비교하지만 list1, list2, seek, target모두 노드라는 걸 꼭 기억해두자

메모리 관리가 새록새록 기억이 나려고 하는 글

파이썬은 레퍼런스로 동작하니깐~!~!
https://stackoverflow.com/questions/58759348/when-does-a-pointer-to-a-linked-list-change-the-actual-list

profile
looooggi

0개의 댓글