Light Blue Pointer
본문 바로가기
Coding Test

2-2. Add two numbers

by Craft Fiend 2023. 10. 14.

옛날에 풀었는데 새로운 풀이가 생각나서 다시 한번 풀어봄

옛날 풀이: https://greedydeveloper.tistory.com/34

 

2. Add Two Numbers

Given Problem You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the .two numbers and return the sum as a linked list. You may assume

greedydeveloper.tistory.com

1. 문제

2. 테스트코드

3. 내가 제출한 코드

4. 풀이과정

1. Given Problem

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the .two numbers and return the sum as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Input: l1 = [2,4,3], l2 = [5,6,4]
Output: [7,0,8]
Explanation: 342 + 465 = 807.

Example 2:

Input: l1 = [0], l2 = [0]
Output: [0]

Example 3:

Input: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
Output: [8,9,9,9,0,0,0,1]

2.Test code

vs code에서 테스트할때 사용한 코드

class ListNode:
    def __init__(self,val=0, next=None):
        self.val = val
        self.next = next

class Solution:



    def main():

        def makeListNode( l:ListNode):
            res = ListNode()
            temp = res

            for i in range(len(l)):
                temp.val = l[i]
                temp.next = ListNode()
                temp = temp.next
            temp.next = None    
            return res

        def printListNode( l:ListNode):
            temp = l
            while (temp.next != None):
                print(temp.val)
                temp = temp.next
            else:
                print(temp.val)

        def addTwoNumbers( l1:ListNode, l2: ListNode):

            print("res")

            #l1 리스트화
            temp = l1
            numberlist1 = []
            while(temp.next!=None):
                numberlist1.insert(0,temp.val)
                print("temp.val"+str(temp.val))
                temp = temp.next
                
            numberlist1.insert(0,temp.val)

            #스트링화   
            str1 = ""
            for x in numberlist1:
                str1 = str1 + str(x)
                print("str1"+str1)
        

            #l2 리스트화
            temp = l2
            numberlist2 = []
            while(temp.next!=None):
                numberlist2.insert(0,temp.val)
                print("temp.val"+str(temp.val))
                temp = temp.next
            numberlist2.insert(0,temp.val)

            #make it into a string
            str2 = ""
            for x in numberlist2:
                print("str2"+str2)
                str2 = str2 + str(x)
            

            #더하기 연산
            num1 = int(str1)
            print(num1)
            num2 = int(str2)
            print(num2)
            num3 = num1+num2
            print(num3)
        
            #결과 스트링화
            str3 = str(num3)
            #뒤집어서 넣어야 함 
            str3 = str3[::-1]

            res = ListNode()
            temp = res
        
            #Listnode화
            for x in str3:
                temp.val = int(x)
                temp.next = ListNode()
                temp = temp.next
                
            temp.next = None    
            return res
        
        print ("test")

        L1 = [2,4,3]
        l1 = makeListNode( L1)
        printListNode(l1)


        L2 = [5,6,4]
        l2 = makeListNode(L2)
        printListNode(l2)

        res = addTwoNumbers(l1, l2)
        print("res")
        printListNode(res)



    if __name__ == "__main__":
        main()

 

3. Submitted Code

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:

        # read
        temp = l1;
        r1=0;
        i1 = 1;
        while (temp.next != None):
            r1 = r1 + (i1)*temp.val
            i1=i1*10
            temp = temp.next
        else:
            r1 = r1 + (i1)*temp.val

        temp = l2;
        r2=0;
        i2 = 1;
        while (temp.next != None):
            r2 = r2 + (i2)*temp.val
            i2=i2*10
            temp = temp.next
        else:
            r2 = r2 + (i2)*temp.val

        r3 = r1 + r2

        #write

        l = list(map(int, str(r3)))
        l = list(reversed(l))
        #l.pop() 여기나 index에서 처리하면 마지막 숫자가 사라지고 그냥 0이 그자리로 감

        res = ListNode()
        temp = res;

        for i in range(len(l)):
            temp.val = l[i]
            temp.next = ListNode()
            temp = temp.next

        #res = res.next 하면 맨 앞이 사라짐 맨 뒤가 아니라 ㅋ

        temp = res;
        while(temp.next.next):
            temp = temp.next

        temp.next = None
        return res;

 

4. 풀이과정

저번에 숫자를 10 곱해서 만들다가 올림,내림,소숫점 자리에서 틀어지는걸로 너무 스트레스받아서

걍 스트링으로 풂

 

꿀팁 1. How to reverse String

str3 = str3[::-1]

옛날에 뒤집은 방법

l = list(map(int, str(r3)))
l = list(reversed(l))

 

문제 1. 하다가 Time limit exceeded가 계속 떠서 스트레스 받던 중

내가 절대 달성할 수 없는 조건을 반복문에 부여했다는 걸 깨달음

temp = l1
numberlist1 = []
while(temp.next!=None):
	print(temp.val)
	numberlist1.insert(0,temp.val)
numberlist1.insert(0,temp.val)

테스트하는데 이 while문에서 안 나와짐

temp.next가 None일 때가 없나보다고 생각함

그리고 계속 보다보니 내가 temp=temp.next를 안 했음

 

⭐. forEach만 쓰다보니 자동으로 넘겨지는게 습관된 거 같음 주의해야겠음

⭐. time exceed 뜨면 일단 루프문에서 뭐가 잘못되었는지 보세요

 

그러고 나서는 입력값에 상관없이 값이 다 642가 나와서 당황스러웠음 

테스트하다보니 내가 range() 용법을 헷갈렸다는 걸 깨달음

#make it into a string
str2 = ""
	for x in range (len(numberlist2)):
	print("str2"+str2)
	str2 = str2 + str(x)

이러고 있었다 ㅎㅎ

for x in numberlist2라고 해야지 len(numberlist2)라고 하면 어떡하나요?

인덱스랑 헷갈릴까봐 인덱스 쓸때는 i,j쓰는데 range안 쓸때는 x쓰기로 정했음

하지만 그러면 뭐하나요 그냥 당연한듯이 range를 씀

약간 코드짤때 제일 처음 배운 언어가 자바여서 그런가 자바로 먼저 생각하고 파이썬 문법으로 번역하는데 

자바는 for i 하고 인덱스가 for문에 있어서 그런가 아 파이썬으로 바꾸려면 range! 이렇게 자동적으로 사고가 되는 거 같다

앞으로는 이 부분을 더 주의해야겠다

 

⭐. for문 쓸때 range써야하는지 안 써야하는지 잘 체크하기

 

그리고 마지막 노드가 자동으로 생성되고 추가된 후에 루프문이 끝나서 

그거 제거해주는 작업을 함

 

처음에는 이렇게 했는데

temp = res
beforetemp = res
while(temp.next):
	beforetemp = temp
	temp = temp.next
beforetemp.next = None

이것보다 더 효율적인 코드가 있었음 나의 예전 풀이에 ㅎㅎ..

 

그래서 이렇게 바꿈

temp = res;
while(temp.next.next):
	temp = temp.next
temp.next = None

⭐. 다음다음노드의 속성 .속성.속성으로 간편하게 읽을 수 있다

⭐. while 안은 None이 아니고 값만 있으면 true로 취급된다