반응형
Leetcode 문제를 풀어가면서 느끼고 문제를 풀기전에 먼저 생각해봤으면 좋았을 내용을 하나씩 더해간다. 물론 없어지기도 하고 관련 있는 내용은 합치기도 한다.
알고리즘을 풀면서 기억하기
- divide and conquer(quick sort, merge sort)
- Heap, PriorityQueue
- while문에서 pq.size()를 꼭 확인하자.
- 우선순위 큐를 이용해보자
- https://silvergoni.tistory.com/entry/programmers%EC%9D%B4%EC%A4%91%EC%9A%B0%EC%84%A0%EC%88%9C%EC%9C%84%ED%81%90
- https://silvergoni.tistory.com/entry/programmers%EB%94%94%EC%8A%A4%ED%81%AC-%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC
- https://silvergoni.tistory.com/entry/programmers%EB%8D%94-%EB%A7%B5%EA%B2%8C
- https://silvergoni.tistory.com/entry/programmers%EC%A3%BC%EC%8B%9D%EA%B0%80%EA%B2%A9
- https://silvergoni.tistory.com/entry/leetcode-347-Top-K-Frequent-Element
- Map
- value기준으로 순서정렬하는거 익혀두자.
- 배열
- 중복제거 하기
- swap으로 처리하기
- 뒤에서부터 읽으면 어떻게 처리될지 생각해보자.
- edge케이스 처리를 신경쓰자
- 인덱스 위치 기억하기
- 머지하기
- 요소를 이동해야한다면 쉬프트 말고 다른 방식이 있을지 고민해보자.
- String.compareTo를 잘 이용해보자.
- Arrays.copyOfRange()
- left,right로 접근하기
- 떄론 정렬을 미리 해두고 풀면 좋다. int[]라면 reverseOrder보다는 인덱스를 뒤에서 접근하는 방식으로 풀어보자.
- 길이가 고정이라면 전역변수로 row, col 길이를 선언해두면 편리하다.
- 정렬된 array라면 포인터 사용도 염두해보자
- dfs
- visited를 설정해서 풀어본다.
- bfs
- visited를 설정해서 풀어본다.
- 방향이 있다면 미리 static하게 선언해주면 코딩이 깔끔해진다.
- 재귀함수
- 재귀함수는 본 솔류션을 메소드로 이용하기보단 서브메소드를 하나 만들어서 확인해보는게 더 빠르다.그 뒤에 가능하다면 본 메소드를 이용하여 재귀를 리팩토링하는 과정을 거친다.
- 구현
- 시간복잡도가 뚜렷하다면 일단 생각나는 방식이 조금은 노가다성일지라도 바로 구현해보면 좋다. 최적시간복잡도가 아니어도 기준시간이상(임의로 시간을 정해서, 내기준 10분) 구상이 안된 상황에서 brute force방법이라도 생각난다면 일단 구현해보자.
- TreeNode
- inorder, postorder, preorder를 완전히 이해했는가?
- bfs
- postorder
- stack을 이용할 때, 넣는 순서를 조심하자.
- preorder
- dfs의 left부터 훝는 것을 이용해서 풀어볼 수 있다.
- 완전 이진 트리를 이해한다.
- queue의 LinkedList에 사용되는 메소드는 offer와 poll이다.
- arraylist output을 사용할때, add와 set을 이용할 수 있다.
- 모든 노드를 비교할 때는 null을 예외처리하지 않고 비교구문에 넣는다.
- recursive-buttomup, recusrive-topdown, iterative-dfs, iterative-bfs 이렇게 다 생각해보자.
- inorder
- Morris Traversal을 기억해두자.
- lefttreeNode를 먼저 stack에 넣어주는 포인트가 있다.
- 링크드리스트
- 노드를 deep copy하자
- 두 노드의 덧셈
- edge케이스를 확인하자.
- 두 노드를 이어보자
- two pointer이용해서 풀기
- head앞에 더미를 이용해서 풀어보자(노드 제거하는 문제는 항상 기억하자)
- 길이를 이용해서 문제를 접근해보자
- 링크드 리스트 개념
- 두개의 특징을 나눠서 연결하고 꼬메기
- 그림을 보고 연상해서 연결을 생각해보는게 빠르게 푸는 방법이다.
- cycle문제가 나오면 floyd, hashSet 두개를 떠올려보자.
- 링크드리스트 reverse하는건 익혀두는게 좋다.
- 링크드리스트에서 중간노드를 찾는건 fast, slow수법을 사용해보자
- int
- palindrome
- 문제가 나오면 반을 어떻게 나눌까 혹은 어떻게 하면 뒷부분을 뒤집어서 비교할 수 있을까를 고민해보자.
- search
- binarysearch에서는 while문을 돌린다면 left, right 중에 하나만 움직인다.
- binarysearch에서는 가운데점을 잡을 때, left + (right - left)/2 형태로 한다.
- binarysearch 기초 다지기
- string
- 뒤집는다고 할때는 stack과 pointer를 생각해서 풀어보자.
- 포인터 left, right로 풀어본다.
- 앞에 것이 사라지는 스펙이라면 뒤에서부터 접근해볼만 했다.
- 데이터를 넣었다가 다시 순서대로 빼준다면 stack을 써보자.
- sort
- merge sort(top-down,bottom-up)은 알아두자
- 그리디, greedy
- 완전탐색
- 그래프
- 인접 노드를 리스트로 묶어서 풀어볼 수 있다.
- 그래프 UnionFind를 써서풀어보기
- disjoint set의 quick union을 사용하여 path compression까지 적용한 방법으로 풀어본다.
- 백트래킹
- 그래프와 유사하지만 본질은 백트래킹
- 방문 여부
- 숫자만 있다면 -1을 곱해서 방문 여부를 확인해볼 수 있다.
- 기타
- 리턴이 2개 필용한 경우는 파라미터에 array를 추가하여 해결해 볼 수 있다.
- treeMap의 특성을 이용하면 더 코드를 간단하게 할 수 있다.
- 방문여부 체크할 때는 boolean[] visited를 선언해서 풀어보자.
- null이 들어올 떄 처리를 잊지말자.
- LinkedList ret = new LinkedList<>(); 로 하면 addFirst메소드를 사용하면 앞에서부터 저장할 수 있다.
- stack은 LinkedList를 써서 push, pollLast메소드를 사용하면 좋다.
- queue는 LinkedList를 써서 add, remove메소드를 사용하면 좋다.
- 요소 위치를 리턴한다면 정렬은 생각에서 배제해보자.
누적사용 설명서
- 제한값이 있는지 확인한다.
- 최대 시간복잡도나 최대 경우의 수를 유추해본다.
- 기본으로 주어지는 메소드에서 해결이 가능한지 생각해본다. > 메소드를 만들어 사용한다. > 전역변수를 과감히 도입한다.
- recursion(Brute Force, Back Tracking)으로 가능할지 먼저 생각해본다. 이 후에 iterative하게 풀 수 있을지도 생각해본다. iteratvie하게 풀때는 stack을 이용해본다. 경우의 따라 queue를 사용해볼 수 있다.
- recursion일 경우, 종료조건을 먼저 만들고 로직을 만든다.
- 주어진 Input데이터를 더렵힐 수도 있다고 생각해본다. 덮어쓰기한다던지, 더해서 합값으로 치환한다던지 말이다.
- TreeNode는 left,right,val으로 구성해볼 수 있고 ListNode는 val,next로 구성해볼 수 있다.
- ListNode문제가 나오면 꼭 그림으로 next관계를 이해해보자. 그리고 기존의 데이터를 이용해서 이어잘라붙이기에 대한 시도도 꼭 해보자.
- 배열에서 갯수를 센다고 하면 Brute force, HashMap, Sorting방법을 생각해보자.
- 만약에 대다수를 구하는 문제라면 Boyer–Moore majority vote algorithm를 생각해보자.
- Arrays 디버깅할때 Arrays.stream(nums).boxed().forEach(System.out::println);하면 결과를 볼수 있다.
- 순서, 부호를 이용해서 공간을 절약할 수 있는지 생각해본다.
- 간단한것 부터 생각해본다. 배열이 있다면 인덱스를 양방향으로 사용하기보다는 한방향으로 사용해보고 정안되면 양방향으로 생각을 바꿔보자. 간단하게 생각하고 간단하게 문제를 만들줄 알아야한다.
- 값을 원하는지 요소를 원하는지 확인해라. 일반적으로 값을 구하는게 더 간단하게 풀 수 있다.
- dp라고 생각되면 꼭 캐쉬를 염두해두자. dp로 풀때는 큰문제를 작은문제로 쪼갤 수 있다는 것이고 그런게 보이면 조건, 초기화, 공식에 대해 한번 확인해보자.
- divide and conquer 방법도 가능한지 생각해보자. https://silvergoni.tistory.com/entry/leetcode-53-Maximum-Subarray
- 자료형이 LinkedList일때 순환의 3가지 풀이법에는 HashSet, Arrays.sort, Floyd tortoise and hare 방법이 있다.
https://silvergoni.tistory.com/entry/leetcode-141-Linked-List-Cycle - linkedList문제가 나오면 17번도 기억하고 공간의 사용없이 순서를 변경할 수 있다는 것도 기억하자. silvergoni.tistory.com/entry/leetcode-234-Palindrome-Linked-List
- 쌍으로 짝을 맞추는게 있다면 stack을 한번 사용해보라. https://silvergoni.tistory.com/entry/leetcode-20-Valid-Parentheses
- Greedy풀이 방법으로의 접근 https://silvergoni.tistory.com/entry/leetcode-53-Maximum-Subarray
- 구간의 확장 문제도 Greedy로 풀 수 있다. https://silvergoni.tistory.com/entry/leetcode-763-Partition-Labels
- 이진법 문제가 나오면 비트 연산을 생각하고 쉬프트연산도 생각해서 풀어보자. https://silvergoni.tistory.com/entry/leetcode-338-Counting-Bits
- 트리에서 Inorder traverse가 필요하다면 morris방법을 기억해두자. https://silvergoni.tistory.com/entry/leetcode-94-Binary-Tree-Inorder-Traversal https://silvergoni.tistory.com/entry/leetcode-230-Kth-Smallest-Element-in-a-BST
- bitmask를 모두 찍어낼 수 있는 방법을 꼭 기억하자. https://silvergoni.tistory.com/entry/leetcode-78-Subsets
- 문제의 조건을 유심히 보고 특히 종료 조건이 있다면 거기서부터 풀이를 생각해보자. https://silvergoni.tistory.com/entry/leetcode-739-Daily-Temperatures
- bst면 그 특성을 이용하라. https://silvergoni.tistory.com/entry/leetcode-230-Kth-Smallest-Element-in-a-BST
- 양퍼버젼으로 풀기 palindromic https://silvergoni.tistory.com/entry/leetcode-647-Palindromic-Substrings
- k-th를 푸는법은 priorityQueue, array라면 quicksort를 이용해본다. https://silvergoni.tistory.com/entry/leetcode-215-Kth-Largest-Element-in-an-Array https://silvergoni.tistory.com/entry/leetcode-347-Top-K-Frequent-Element
- dp스럽다고 생각되는 문제가 나오면 결국 얻고자하는 요소를 결정하는 요소들의 비교를 어떻게 해야하는지 확인해보고 그걸 유한하게 만들려면 어디서부터 출발해야할지 결정할 수 있다. https://silvergoni.tistory.com/entry/leetcode-64-Minimum-Path-Sum
- 재귀로 넘어가는데 재귀당 다음 재귀로의 방법을 recursive, iterative하게 할 수 있는데 이는 다시 말해서 bfs와 dfs로 풀 수 있기도 한 것이다. https://silvergoni.tistory.com/entry/leetcode-200-Number-of-Islands
- 트리에서 부모를 찾는 문제라고 생각되면 사실 그건 recursion으로 어떤 값을 리턴할지 그리고 그 리턴값의 판단은 무엇으로 할지의 문제로 해석해보는게 좋다. https://silvergoni.tistory.com/entry/leetcode-236-Lowest-Common-Ancestor-of-a-Binary-Tree
- 자료형을 파악 -> 배열이면 앞,뒤 접근 선택 -> dp라면 상태값을 파악 -> 상태값에 영향주는 요소를 파악 -> 식으로 구성 https://silvergoni.tistory.com/entry/leetcode-309-Best-Time-to-Buy-and-Sell-Stock-with-Cooldown
- 합 문제는 되도록 합을 파라미터로 이용하자. 게다가 그 합에 갯수를 구하는 문제라면 합별 개수를 카운트 한걸 map에 저장해보도록 하자. https://silvergoni.tistory.com/entry/leetcode-437-Path-Sum-III
- 링크드리스트에 소팅은 merge sort로 해보자 https://silvergoni.tistory.com/entry/leetcode-148-Sort-List
- anagram같이 여러 요소로 구성된 부분집하을 찾을때 키를 만들어 풀어보자 https://silvergoni.tistory.com/entry/leetcode-49-Group-Anagrams https://silvergoni.tistory.com/entry/leetcode-39-Combination-Sum https://silvergoni.tistory.com/entry/leetcode-438-Find-All-Anagrams-in-a-String
- 합의 문제에서 제한적인 합이라면 dp로 접근해서 풀어보자. https://silvergoni.tistory.com/entry/leetcode-416-Partition-Equal-Subset-Sum https://silvergoni.tistory.com/entry/leetcode-494-Target-Sum
'알고리즘 풀이' 카테고리의 다른 글
.leetcode(261. Graph Valid Tree) (0) | 2022.04.12 |
---|---|
.leetcode(547. Number of Provinces) (0) | 2022.04.11 |
.programmers(조이스틱) (0) | 2022.04.09 |
.programmers(체육복) (0) | 2022.04.09 |
.programmers(카펫) (0) | 2022.04.09 |