전체 글
[LeetCode] 1448. Count Good Nodes in Binary Tree (C#)
https://leetcode.com/problems/count-good-nodes-in-binary-tree/ Root 노드부터 현재 노드(X)까지 이동하는 동안 자신(X)보다 큰 값을 가진 노드가 없는 경우 X는 GoodNode가 된다.이때 주어진 이진 트리의 GoodNode 개수를 구하는 문제. 1. 풀이현재 노드의 값이 지금까지 지나온 값들과 비교해 같거나 크면 GoodNode 카운팅namespace PS.LeetCode;public class Solution_1448_1{ public int GoodNodes(TreeNode root) { var result = 0; Dfs(root, root.val, ref result); return resu..
[LeetCode] 328. Odd Even Linked List (C#)
https://leetcode.com/problems/odd-even-linked-list/description/ 홀수번째 Node를 앞으로 당겨오고, 짝수번째 Node를 뒤로 밀어주는 문제. 제한 사항공간 복잡도 : O(1)시간 복잡도 : O(N) 1. 풀이더 이상 Odd 노드가 없을 때까지 Odd는 Odd끼리, Even은 Even끼리 연결마지막에 Odd의 tail과 Even의 head를 연결namespace PS.LeetCode;public class Solution_328_1{ public class ListNode { public int val; public ListNode next; public ListNode(int val = 0, ListN..
[LeetCode] 2095. Delete the Middle Node of a Linked List (C#)
https://leetcode.com/problems/delete-the-middle-node-of-a-linked-list linkedlist의 head가 주어진다.해당 linkedlist의 middle 노드를 삭제하고, 변경된 리스트의 head를 반환하는 문제.middle 노드의 기준은 리스트의 사이즈를 n이라고 가정하고 [ n / 2 ] 번째 노드를 뜻한다. 1. 원 포인터를 사용한 풀이middle 노드가 몇 번째인지 확인하는 과정이 들어간다.middle 노드 직전에서 순회를 멈추고 다다음 노드를 Next 로 바라본다.원소가 1개인 경우는 예외 케이스로 처리public class ListNode { public int val; public ListNode next; public L..
[LeetCode] 238. Product of Array Except Self (C#)
https://leetcode.com/problems/product-of-array-except-self/nums[i] 자신을 제외한 다른 모든 원소의 곱을 answer[i] 에 입력하여 반환하는 문제.nums 배열 원소의 prefix product 값과 suffix product 값은 32bit 정수값이 되도록 주어진다. 제한사항시간복잡도 O(n)나눗셈 연산 사용 불가 1. 나눗셈 연산을 사용했을 때의 답안결과가 0 이 되는 경우를 분리하여 코드를 구성한 번에 이해하기 어려운 조건식list 배열을 사용하여 불필요한 Array 변환 과정이 있음public class Solution { public int[] ProductExceptSelf(int[] nums) { var pro..
[More Effective C#] Chapter 4. 요약 (2)
[ Item 40 : 동기화에는 lock()을 최우선으로 사용하라 ]스레드들은 서로 통신할 수 있어야 한다.즉, 같은 애플리케이션에 속한 스레드들은 데이터를 안전하게 주고받을 수 있는 수단이 있어야 한다. 데이터 무결성 오류로 인한 잠재적 문제를 피하려면 모든 공유 데이터의 상태가 일관되게 유지되고 있음을 확신할 수 있어야 하고, 그렇게 하려면 동기화 요소(synchronization primitive)를 사용해서 공유 데이터에 대한 접근을 제어해야 한다. 동기화 요소는 특정 스레드가 임계 영역 내에서 연산을 수행하는 동안 다른 스레드로부터 이를 보호하는 역할을 수행한다.그래서 C# 에서는 동기화 작업을 수월하게 할 수 있도록 lock() 블록을 사용해서 임계 영역을 지정하고, 동기화를 올바르게 제어할 ..
[More Effective C#] Chapter 4. 요약 (1)
[ Item 35 : PLINQ가 병렬 알고리즘을 구현하는 방법을 이해하라 ] PLINQ 를 사용하면 멀티코어 프로그래밍에 쉽게 접근할 수 있다. 데이터 접근을 위해 언제 동기화돼야 하는지 알아야 한다. ParallelEnumerable에 선언된 병렬 버전과 순차 버전 메서드의 효과를 측정해야 한다. 개별 요소들을 반드시 순차적으로 접근해야만 하는 메서드가 있다는 것을 알아야 한다. PLINQ를 사용하는 예시 150 보다 작은 모든 수에 대해 n! 을 계산하는 쿼리 var nums = data.Where(d => d Factorial(n)); 파이프라인의 첫 번째 메서드에 AsParallel()을 추가하면 병렬 연산이 가능해진다. var nums = data.AsPara..
[More Effective C#] Chapter 3. 요약 (2)
[ Item 31 : 불필요한 콘텍스트 마샬링을 피하라 ] 현재 아이템은 SynchronizationContext와 관련된 성능 문제를 다룬다. 특히, 멀티스레딩 환경에서 특정 Context로의 데이터 전달이나 메서드 호출이 필요할 때 발생하는 마샬링 오버헤드를 최소화하는 방법을 집중해서 다룬다. ‘자유 코드’ 어떤 context에서도 실행될 수 있는 코드 우리가 작성하는 대부분의 코드는 자유 코드이다. ‘Context 인식 코드’ 특정 SynchronizationContext 에서만 실행될 수 있는 코드 GUI 애플리케이션에서 UI 컨트롤과 상호작용하는 코드 웹 애플리케이션에서 HTTPContext 등의 클래스와 상호작용하는 코드 콘텍스트 마샬링이란? 하나의 스레드에서 다른 스레드로 데이터를 전달하거나..
[More Effective C#] Chapter 3. 요약 (1)
[ Item 27 : 비동기 작업에는 비동기 메서드를 사용하라 ] 동기 메서드에서는 코드들이 작성한 순서대로 실행된다. 하지만 비동기 메서드에서는 꼭 그렇지 않을 수 있다. 비동기 메서드는 내부 코드를 모두 수행하기 전에 미리 반환될 수 있으며, 내부적으로 요청한 비동기 작업이 완료되는 시점에 맞추어 수행을 중단했던 지점부터 다시 수행을 이어간다. private async Task SomeMethodAsync() { Console.WriteLine($"Entering {nameof(SomeMethodAsync)}"); var awaitable = SomeMethodReturningTask(); Console.WriteLine($"In {nameof(SomeMethodAsync)}, before the a..
[More Effective C#] Chapter 2. 요약 (2)
[ Item 19 : 베이스 클래스에 정의된 메서드를 오버로드해서는 안된다 ] 베이스 클래스에서 정의된 메서드를 파생 클래스에서 오버로드하면 어떤 메서드가 호출될지 정확히 이해하기가 어려워진다. 1. 명확한 메서드 이름을 사용한다 해당 기능을 명확하게 설명하는 이름을 지어주자. 2. 오버라이딩을 통해 기능을 확장한다 기존 메서드의 기능을 수정하거나 확장해야 할 때는, 오버라이딩을 사용하자. 3. 메서드 오버로딩 최소화 베이스 클래스의 메서드와 동일한 이름을 가진 새로운 메서드를 추가할 필요가 있을 때는, 혼란을 피하기 위해 가능한 한 메서드 오버로딩을 피하고 다른 이름을 지어주자. [ Item 20 : 이벤트가 런타임 시 객체 간의 결합도를 증가시킨다는 것을 이해하라 ] 이벤트 기반 API에는 결합도를 ..
[More Effective C#] Chapter 2. 요약 (1)
[ Item 11 : API에는 변환 연산자를 작성하지 말라 ] 1. 다른 타입을 원하는 커스텀 타입으로 변환하고 싶을 때는 생성자를 사용하라. 생성자는 새로운 객체를 만든다는 사실을 명확히 알려준다. public class Circle { ... static public implicit operator Ellipse(Circle c) { return new Ellipse(...) } } public static void Flatten(Ellipse e) { e.r1 /= 2; } var c = new Circle(...); Flatten(c); // Circle -> Ellipse 로 암묵적 변환 따라서 위와 같은 상황에서 Flatten() 함수는 암묵적 변환 과정에서 새롭게 생성된 Ellipse 객체..