-
-
Notifications
You must be signed in to change notification settings - Fork 305
[haxr369] WEEK 08 solutions #2245
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
3b448ca
feat: reverse bits
haxr369 4a0f437
feat: longest-repeating-character-replacement 풀이
haxr369 d4b7d87
feat: clone-graph 풀이
haxr369 2be3caf
Merge branch 'DaleStudy:main' into main
haxr369 169b91c
feat: linked-list-cycle sovle
haxr369 fb3b280
feat: pacific-atlantic-water-flow solve
haxr369 1fdecec
feat: pacific-atlantic-water-flow solve
haxr369 083dd82
Delete linked-list-cycle/Solution.java
haxr369 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| /** | ||
| * Runtime: 25 ms (Beats 72.12%) | ||
| * Memory: 44.35 MB (Beats 34.32%) | ||
| * Space Complexity: O(N) | ||
| * - 모든 노드 저장 => O(N) | ||
| * - visited로 복사했던 노드 관리 => O(N) | ||
| * > O(N) | ||
| * Time Complexity: O(N) | ||
| * - 루트노드부터 모든 노드까지 한번씩 탐색 => O(N) | ||
| * > O(N) | ||
| * | ||
| */ | ||
|
|
||
| class Node { | ||
| public int val; | ||
| public List<Node> neighbors; | ||
|
|
||
| public Node() { | ||
| val = 0; | ||
| neighbors = new ArrayList<Node>(); | ||
| } | ||
|
|
||
| public Node(int _val) { | ||
| val = _val; | ||
| neighbors = new ArrayList<Node>(); | ||
| } | ||
|
|
||
| public Node(int _val, ArrayList<Node> _neighbors) { | ||
| val = _val; | ||
| neighbors = _neighbors; | ||
| } | ||
| } | ||
|
|
||
| class Solution { | ||
| public Node cloneGraph(Node node) { | ||
| if (node == null) { | ||
| return node; | ||
| } | ||
|
|
||
| if (node.neighbors == null) { | ||
| Node newNode = new Node(node.val, null); | ||
| return newNode; | ||
| } else if (node.neighbors.isEmpty()) { | ||
| Node newNode = new Node(node.val, new ArrayList<>()); | ||
| return newNode; | ||
| } | ||
|
|
||
| Node[] visited = new Node[104]; | ||
|
|
||
| Node ans = new Node(node.val, new ArrayList<>(node.neighbors)); | ||
| visited[ans.val] = ans; | ||
| dfs(ans, visited); | ||
|
|
||
| return ans; | ||
| } | ||
|
|
||
| /** | ||
| * node의 리스트를 dfs로 변경해간다. | ||
| * 다만, 변경했던 노드는 다시 변경하지 않음 | ||
| */ | ||
| private void dfs(Node node, Node[] visited) { | ||
|
|
||
| List<Node> neighbors = node.neighbors; // 이전 것 | ||
|
|
||
| List<Node> newNeighbors = new ArrayList<>(); // 새 껍질 | ||
| // 하나씩 새걸로 바꾸자 | ||
| for (Node n : neighbors) { | ||
| if (visited[n.val] != null) { | ||
| newNeighbors.add(visited[n.val]); | ||
| continue; | ||
| } | ||
| Node newN = new Node(n.val, new ArrayList<>(n.neighbors)); // 껍질 만들기 | ||
| visited[newN.val] = newN; | ||
| dfs(newN, visited); // | ||
| newNeighbors.add(newN); | ||
| } | ||
| node.neighbors = newNeighbors; // 신규 리스트로 바꿔치기 | ||
| // printNode(node); | ||
| } | ||
|
|
||
| private void printNode(Node node) { | ||
| System.out.print("val -> " + node.val); | ||
| System.out.println(" size -> " + node.neighbors.size()); | ||
| node.neighbors.forEach(n -> System.out.print(n.val)); | ||
| System.out.print('\n'); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| import java.util.HashMap; | ||
| import java.util.Iterator; | ||
| import java.util.Map; | ||
|
|
||
| /** | ||
| * Runtime: 105 ms (Beats 5.05%) | ||
| * Memory: 46.94 MB (Beats 25.55%) | ||
| * Space Complexity: O(1) | ||
| * > 26개 영문자에 대한 Hash 테이블 => O(26) => O(1) | ||
| * Time Complexity: O(N) | ||
| * - 윈도우를 문자열 길이만큼 이동시키기 => O(N) | ||
| * - 윈도우 변경할 때마다 최소변경필요개수 구하기 => O(26) => O(1) | ||
| * > O(N)xO(1) => O(N) | ||
| * | ||
| */ | ||
| class Solution { | ||
| /** | ||
| * 슬라이딩 윈도우 기법 사용 | ||
| * | ||
| * 1. 시작인덱스, 종료인덱스 설정. | ||
| * 2. 윈도우 안에 변경 필요 건수가 k 보다 크면 시작인덱스 늘리기 => 변환할 수 없기 때문에 | ||
| * 3. 만약 변경 필요 건수가 k와 작거나 같다면 종료인덱스 늘리기 => 변환 가능한 유효한 문자열이기 때문 | ||
| */ | ||
| public int characterReplacement(String s, int k) { | ||
| int strIdx = 0; | ||
| int endIdx = 0; | ||
| int visited = -1; // visited 문자까지는 윈도우에 들어갔기 때문에 넣지 않는다. | ||
| int ans = 0; | ||
|
|
||
| // 윈도우 상태 관리 | ||
| Map<Character, Integer> winState = new HashMap<>(); | ||
|
|
||
| while (s.length() > endIdx) { | ||
|
|
||
| // endC를 윈도우에 추가하기 | ||
| if (visited < endIdx) { // 두번 넣지 않게 방어막 쳐주기 | ||
| Character endC = Character.valueOf(s.charAt(endIdx)); | ||
| int temp = winState.getOrDefault(endC, 0); | ||
| winState.put(endC, temp + 1); | ||
| visited++; | ||
| } | ||
|
|
||
| // 유효성 검사하기 O(26) | ||
| int minChng = cntMinChng(winState, endIdx - strIdx + 1); | ||
| if (minChng <= k) { // 유효한 상태 | ||
| ans = Integer.max(ans, endIdx - strIdx + 1); | ||
| endIdx++; | ||
| } else { // 유효하지 않은 상태 | ||
| Character strC = Character.valueOf(s.charAt(strIdx)); | ||
| // 뒷자리 하나 빼기 | ||
| int temp = winState.getOrDefault(strC, 0); | ||
| winState.put(strC, temp - 1); | ||
| strIdx++; | ||
| } | ||
| } | ||
| return ans; | ||
| } | ||
|
|
||
| /** | ||
| * 시간복잡도 => O(26) | ||
| * 윈도우에서 최소변경필요개수 카운트 | ||
| * 변경해야할 최소 값 = 현재 윈도우 길이 - (가장 많이 등장한 문자 개수) | ||
| */ | ||
| private int cntMinChng(Map<Character, Integer> winState, int winLen) { | ||
| int minChng = Integer.MAX_VALUE; | ||
| Iterator<Map.Entry<Character, Integer>> it = winState.entrySet().iterator(); | ||
| // 비어 있다면 0개로 출력 | ||
| if (!it.hasNext()) { | ||
| return 0; | ||
| } | ||
|
|
||
| // 뭔가 있으면 돌리기 | ||
| while (it.hasNext()) { | ||
| Map.Entry<Character, Integer> entry = it.next(); | ||
| int v = entry.getValue(); | ||
| int chng = winLen - v; | ||
| minChng = Integer.min(chng, minChng); | ||
| } | ||
| return minChng; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| import java.util.ArrayList; | ||
| import java.util.Arrays; | ||
| import java.util.LinkedList; | ||
| import java.util.List; | ||
| import java.util.Queue; | ||
|
|
||
| class Solution { | ||
|
|
||
| private final int[] dy = { -1, 1, 0, 0 }; | ||
| private final int[] dx = { 0, 0, -1, 1 }; | ||
| private int M = 0, N = 0; | ||
|
|
||
| /** | ||
| * 특정 노드에서 시작에서 이웃 노드를 거쳐 두 바다로 갈 수 있는 노드 리스트를 출력하기 | ||
| * 특정 노드에서 전체 탐색? => O(NxM) x O(NxM) 탐색 필요. | ||
| * | ||
| * 그럼 태평양, 대서양 각각에서 도달할 수 있는 노드 리스트 찾기(본인 이상 값을 가진 노드로 탐색) | ||
| * 그리고 겹치는 지점 찾기 => 답 | ||
| * 3xO(NxM) | ||
| * | ||
| * Runtime: 11 ms (Beats 28.23%) | ||
| * Memory: 46.9 MB (Beats 98.39%) | ||
| * Space Complexity: O(NxM) | ||
| * - 노드 방문 여부를 체크하기 위한 flowed O(NxM) | ||
| * - 방문하는 노드를 큐에 찾기 qu O(NxM) | ||
| * > 2O(NxM) => O(NxM) | ||
| * Time Complexity: O(NxM) | ||
| * - 태평양 인접 노드 탐색 O(NxM) | ||
| * - 대서양 인접 노드 탐색 O(NxM) | ||
| * - 두 대양 인접 노드 검색 O(NxM) | ||
| * > 3O(NxM) | ||
| */ | ||
| public List<List<Integer>> pacificAtlantic(int[][] heights) { | ||
| M = heights.length; | ||
| N = heights[0].length; | ||
| int[][] flowed = new int[M][N]; // 1이면 태평양 인접, 2면 대서양, 3이면 둘 다, 0이면 인접X | ||
|
|
||
| // (0,0) ~ (0,N-1)을 1로 넣고 bfs 돌리기 | ||
| Queue<int[]> qu = new LinkedList<>(); | ||
| for (int i = 0; i < N; i++) { | ||
| int[] temp = { 0, i }; | ||
| flowed[0][i] += 1; | ||
| qu.add(temp); | ||
| } | ||
| // (1, 0) ~ (M-1, 0) | ||
| for (int i = 1; i < M; i++) { | ||
| int[] temp = { i, 0 }; | ||
| flowed[i][0] += 1; | ||
| qu.add(temp); | ||
| } | ||
| // 태평양 탐색 | ||
| bfs(qu, flowed, heights, 1); | ||
|
|
||
| // printMp(flowed); | ||
|
|
||
| // System.out.println("------------"); | ||
|
|
||
| qu = new LinkedList<>(); | ||
| // (M-1, 0) ~ (M-1, N-1) | ||
| for (int i = 0; i < N; i++) { | ||
| int[] temp = { M - 1, i }; | ||
| flowed[M - 1][i] += 2; | ||
| qu.add(temp); | ||
| } | ||
| // (0, 0) ~ (M-2, N-1) | ||
| for (int i = 0; i < M - 1; i++) { | ||
| int[] temp = { i, N - 1 }; | ||
| flowed[i][N - 1] += 2; | ||
| qu.add(temp); | ||
| } | ||
| // 태평양 탐색 | ||
| bfs(qu, flowed, heights, 2); | ||
| List<List<Integer>> ans = new ArrayList<>(); | ||
|
|
||
| for (int i = 0; i < M; i++) { | ||
| for (int j = 0; j < N; j++) { | ||
| if (flowed[i][j] == 3) { | ||
| List<Integer> tmp = new ArrayList<>(Arrays.asList(i, j)); | ||
| ans.add(tmp); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return ans; | ||
|
|
||
| } | ||
|
|
||
| private void bfs(Queue<int[]> qu, int[][] flowed, int[][] heights, int oceanTp) { | ||
| while (!qu.isEmpty()) { | ||
| int[] node = qu.poll(); | ||
| int h = heights[node[0]][node[1]]; | ||
|
|
||
| // 사방을 보면서 적절한 노드를 큐에 넣기 | ||
| for (int n = 0; n < 4; n++) { | ||
| int ny = node[0] + dy[n]; | ||
| int nx = node[1] + dx[n]; | ||
|
|
||
| // 섬 밖 위치인지 체크 | ||
| if (ny < 0 || ny >= M || nx < 0 || nx >= N) { | ||
| continue; | ||
| } | ||
| // 방문했던 위치면 넘어가기 | ||
| if (flowed[ny][nx] >= oceanTp) { | ||
| continue; | ||
| } | ||
| // 바다에서 섬으로 갈 수 있는 방향인지 체크 | ||
| if (h > heights[ny][nx]) { | ||
| continue; | ||
| } | ||
| flowed[ny][nx] += oceanTp; | ||
| int[] temp = { ny, nx }; | ||
| qu.add(temp); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private void printMp(int[][] mp) { | ||
| int my = mp.length; | ||
| int mx = mp[0].length; | ||
| for (int y = 0; y < my; y++) { | ||
| for (int x = 0; x < mx; x++) { | ||
| System.out.print(mp[y][x] + " "); | ||
| } | ||
| System.out.print('\n'); | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| class Solution { | ||
| /** | ||
| * Runtime: 1 ms (Beats 54.22%) | ||
| * Memory: 42.34 MB (Beats 63.68%) | ||
| * Space Complexity: O(1) | ||
| * > 고정된 32byte 배열 사용으로 O(1) | ||
| * Time Complexity: O(logN) | ||
| * - n의 2진수 변환 => O(logN) | ||
| * - 32bit 역순 변환 => O(1) | ||
| * > O(log32) + O(1) => O(log32) 사실상 O(1) | ||
| * | ||
| */ | ||
| public int reverseBits(int n) { | ||
| byte[] binarys = new byte[32]; | ||
| int temp = n; | ||
|
|
||
| // n의 2진수를 저장하기 | ||
| int i = 0; | ||
| while (temp > 0) { // 최종 0이되면 종료 | ||
| // 짝수인 경우 i번째 비트는 0 | ||
| if (temp % 2 == 0) { | ||
| binarys[i] = 0; | ||
| } else { // 홀수면 i번째 비트는 1 | ||
| binarys[i] = 1; | ||
| temp -= 1; | ||
| } | ||
| temp = temp / 2; | ||
| i++; // 비트수 올리기 | ||
| } | ||
|
|
||
| // 저장된 비트를 역순으로 십진수로 변환하기 | ||
| int ans = 0; // 총합산 | ||
| int base = 1; // i-j번째 2진수 값 | ||
| int j = 0; | ||
| while (31 >= j) { | ||
| // 2진수가 1인 경우만 합산한다. | ||
| if (binarys[31 - j] == 1) { | ||
| ans += base; | ||
| } | ||
| base *= 2; | ||
| j++; | ||
| } | ||
| return ans; | ||
| } | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 원본을 먼저 바이너리 배열로 만들어놓고 역순으로 하는 방법도 있네요ㅎㅎ 👍