서비스 개발 방법론
개발(Development)+ 운영(Operations)
소프트웨어 개발자와 정보기술 전문가 사이의 소통, 협업 및 통합을 강조하는 개발 환경이나 문화
데브옵스(DevOps)는 개발(Dev)과 운영(Ops)을 분리해왔던 기존의 '소프트웨어 개발 생명주기(Software Development Life Cycle, SDLC)' 방법론을 뛰어넘을 수 있게 해줄 것으로 기대
소프트웨어 배포의 속도와 질을 향상시키는 것을 목표로함
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
이렇게 하는 것만으로도 충분하다..
깔끔하당.. 담엔 나도 이렇게 풀어야지
근데 얘네 주르륵 다 넣어주는건가..? 저렇게 주르륵 들어갈 수 있으면..? 주르륵이라고 볼 수 있지만 주르륵이라기보단 헤드의 위치니까.. 무튼 주르륵 넣을 수도 있단 게 중요한거지
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