241126

凡愚·2024년 11월 26일

개발 일지

목록 보기
2/350

✅ 오늘 한 일


  • 리트코드 or 백준 1문제 풀기
  • 이력서 다듬기


📝 배운 것들


🏷️ C# : 변수?.멤버

?.는 C#의 null 조건 연산자 (null-conditional operator)입니다. 이 연산자는 객체가 null인지 확인한 다음, 안전하게 멤버 또는 메서드에 접근할 수 있도록 도와줍니다.

동작 방식

  • l1?.next는 다음과 같이 동작합니다:
    1. l1null이 아니면 l1.next에 접근합니다.
    2. l1null이면 null을 반환합니다.

즉, 이 연산자는 null 참조로 인한 런타임 예외 (NullReferenceException)를 방지합니다.

🏷️ 인터페이스에서 구현을?

https://devblogs.microsoft.com/dotnet/default-implementations-in-interfaces/
https://andrewlock.net/understanding-default-interface-methods/

인터페이스는 구현 없고 다중 상속 가능하고
추상 클래스는 구현 있고 다중 상속 불가능하다고 봤는데
더 찾아보니까 C#이나 Java나 버전 올라오면서 인터페이스에서도 구현하는거 가능하다고 함

대신 상속은 안됨

인터페이스 > 추상 클래스 > 클래스 이런 식으로 상속받았다면
클래스에서 인터페이스를 명시적으로 상속받아야 구현한 거 상속받을 수 있음

죽음의 다이아몬드 문제 발생할 수 있음 (뭘 실행해야되는 건데?)



⚔️ LeetCode


📌 2. Add Two Numbers

public class Solution {
    public ListNode AddTwoNumbers(ListNode l1, ListNode l2) {
        int remain = 0;
        int power_ten = 1;
        ListNode l1Node = l1;
        ListNode l2Node = l2;
        ListNode result = new ListNode();
        while (l1Node.next != null)
        {
            int cur_sum = l1Node.val + l2Node.val + remain;
            remain = 0;
            if (cur_sum >= 10)
            {
                cur_sum -= 10;
                remain = 1;
            }

            l1Node = l1Node.next;
            l2Node = l2Node.next;

            result.val = cur_sum;
            result.next = new ListNode();
            result = result.next;
        }
        return result;
    }   
}

nullref가 왜 뜨는거임?? 했는데
l1과 l2의 길이가 같다는 보장이 없었음

public class Solution {
    public ListNode AddTwoNumbers(ListNode l1, ListNode l2) {
        int remain = 0;
        int power_ten = 1;
        ListNode l1Node = l1;
        ListNode l2Node = l2;
        ListNode result = new ListNode();
        while (l1Node != null || l2Node != null)
        {
            int l1Val = (l1Node != null) ? l1Node.val : 0;
            int l2Val = (l2Node != null) ? l2Node.val : 0;

            int cur_sum = l1Val + l2Val + remain;

            if (cur_sum >= 10)
            {
                cur_sum -= 10;
                remain = 1;
            }

            remain = 0;

            if (l1Node != null) l1Node = l1Node.next;
            if (l2Node != null) l2Node = l2Node.next;

            result.val = cur_sum;
            result.next = new ListNode();
            result = result.next;
        }
        return result;
    }   
}

이젠 답은 나오는데

이따구로 나옴

처음을 줘야 하는데 마지막을 줘서 그런건가?
: 그럼 첫번째 노드만 저장해놓으면 되겠구나

근데 그렇다고 하더라도 8이 나와야지 왜 0이 찍힘?
: 당연한거지 result는 마지막에 무조건 0이 될테니까

public class Solution {
    public ListNode AddTwoNumbers(ListNode l1, ListNode l2) {
        int remain = 0;
        ListNode l1Node = l1;
        ListNode l2Node = l2;
        ListNode firstNode = new ListNode();
        ListNode result = firstNode;
        while (l1Node != null || l2Node != null || remain > 0)
        {
            int l1Val = (l1Node != null) ? l1Node.val : 0;
            int l2Val = (l2Node != null) ? l2Node.val : 0;

            int cur_sum = l1Val + l2Val + remain;

            remain = 0;

            if (cur_sum >= 10)
            {
                cur_sum -= 10;
                remain = 1;
            }

            result.val = cur_sum;

            if (l1Node != null) l1Node = l1Node.next;
            if (l2Node != null) l2Node = l2Node.next;   

            if (l1Node != null || l2Node != null || remain > 0)
            {
                result.next = new ListNode();
                result = result.next;
            }
        }
        return firstNode;
    }   
}

if문 떡칠해서 풀긴 함

remain > 0 조건을 떠올리는것과
while문에도 넣어줘야 한다는 점을 놓쳐서 살짝 시간 소요

        while (true)
        {
            int l1Val = (l1Node != null) ? l1Node.val : 0;
            int l2Val = (l2Node != null) ? l2Node.val : 0;

            int cur_sum = l1Val + l2Val + remain;

            remain = 0;

            if (cur_sum >= 10)
            {
                cur_sum -= 10;
                remain = 1;
            }

            result.val = cur_sum;

            if (l1Node != null) l1Node = l1Node.next;
            if (l2Node != null) l2Node = l2Node.next;   

            if (l1Node == null && l2Node == null && remain == 0)
                break;

            result.next = new ListNode();
            result = result.next;
        }

if문 호출 횟수 개선해서 시간 좀 줄임

public class Solution
    {
        public ListNode AddTwoNumbers(ListNode l1, ListNode l2, int carry = 0)
        {
            if (l1 == null && l2 == null && carry == 0) return null;

            int total = (l1 != null ? l1.val : 0) + (l2 != null ? l2.val : 0) + carry;
            carry = total / 10;
            return new ListNode(total % 10, AddTwoNumbers(l1?.next, l2?.next, carry));
        }
    }

더 빠르게 짠 사람들은 어떻게 풀었나 봤더니
함수 자체를 재귀 함수로 바꿔버림. ?이라는 이상한 문법도 사용.
멤버나 메서드 접근하기 전에 null check하는 문법이라는데 실사용 가능성도 있을지도?

            remain = 0;

            if (cur_sum >= 10)
            {
                cur_sum -= 10;
                remain = 1;
            }

여기서 remain = 0;은 인자에서 초기화해버리고
10보다 크면 다음 자리수의 1로 설정하는 건 carry = total / 10으로 해결함.

0개의 댓글