From 8bd065f00f2ca7f60ca02d6e8001967c5121c573 Mon Sep 17 00:00:00 2001 From: "Yongseok.choi" Date: Mon, 19 May 2025 08:14:40 +0900 Subject: [PATCH 1/3] add: reverse bits --- reverse-bits/YoungSeok-Choi.java | 34 ++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 reverse-bits/YoungSeok-Choi.java diff --git a/reverse-bits/YoungSeok-Choi.java b/reverse-bits/YoungSeok-Choi.java new file mode 100644 index 000000000..a96aa7e21 --- /dev/null +++ b/reverse-bits/YoungSeok-Choi.java @@ -0,0 +1,34 @@ + +class Solution { + public int reverseBits(int n) { + int result = 0; + + for (int i = 0; i < 32; i++) { + // result변수 비트 왼쪽 한칸 시프트. LSB 는 0으로 초기화. + result <<= 1; + + // n 변수의 가장 오른쪽 비트를(LSB) result 변수에 할당. + result = result | (n & 1); + + // n 변수 오른쪽 시프트(넘어가는 비트는 무시) + n >>>= 1; + } + + return 0; + } +} + +class AnotherSolution { + public int reverseBits(int n) { + // NOTE: 이진 배열로변환 (음수의 경우 1로 비트가 표현되기 때문에 양수 경우만 처리.) + String binary = String.format("%32s", Integer.toBinaryString(n)).replace(" ", "0"); + String reverse = new StringBuilder(binary).reverse().toString(); + + // NOTE: int자료형으로 이진수 파싱을 할 때 표현범위 (+- 21억) 가 넘어서게 되면 오류 발생 + // java.lang.NumberFormatException: For input string: + // "10111111111111111111111111111111" under radix 2 + // Long 자료형으로 안전하게 파싱해야함. + return (int) Long.parseLong(reverse, 2); + } + +} \ No newline at end of file From c20c05e411914e8b0626efbba7b79453ed9b49f6 Mon Sep 17 00:00:00 2001 From: "Yongseok.choi" Date: Mon, 19 May 2025 08:16:57 +0900 Subject: [PATCH 2/3] fix: lint --- reverse-bits/YoungSeok-Choi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reverse-bits/YoungSeok-Choi.java b/reverse-bits/YoungSeok-Choi.java index a96aa7e21..b72f27897 100644 --- a/reverse-bits/YoungSeok-Choi.java +++ b/reverse-bits/YoungSeok-Choi.java @@ -31,4 +31,4 @@ public int reverseBits(int n) { return (int) Long.parseLong(reverse, 2); } -} \ No newline at end of file +} From 28c492c4fecc02e90ad1db64eb7d169662e3c979 Mon Sep 17 00:00:00 2001 From: "Yongseok.choi" Date: Tue, 20 May 2025 08:31:41 +0900 Subject: [PATCH 3/3] add: longest repeating chas --- .../YoungSeok-Choi.java | 203 ++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 longest-repeating-character-replacement/YoungSeok-Choi.java diff --git a/longest-repeating-character-replacement/YoungSeok-Choi.java b/longest-repeating-character-replacement/YoungSeok-Choi.java new file mode 100644 index 000000000..218c505fe --- /dev/null +++ b/longest-repeating-character-replacement/YoungSeok-Choi.java @@ -0,0 +1,203 @@ +import java.util.HashMap; +import java.util.Map; + +// NOTE: sliding window 방식으로 풀이했던 답지... 아직 if 구문이나, 반환값의 이유가 이해되지 않았다. 별도로 정리 + 한번 더 풀어보기. +// TC -> O(n) +class Solution { + public int characterReplacement(String s, int k) { + Map cMap = new HashMap<>(); + + int mx = 0; + int left = 0; + + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + + cMap.put(c, cMap.getOrDefault(c, 0) + 1); + + mx = Math.max(mx, cMap.get(c)); + + if (i - left + 1 - mx > k) { + cMap.put(s.charAt(left), cMap.getOrDefault(s.charAt(left), 0) - 1); + left++; + } + } + + return s.length() - left; + } +} + +// NOTE: 구현에 시간이 너무 오래걸려 일단 스킵.. (현재 알고리즘에서 최대 연속되는 빈도들의 후보군들을 정하고, 그 후보군들만 +// 치환해보는 방식을 사용해도 될 것 같다...) +class WrongSolution { + public int characterReplacement(String s, int k) { + + if (s.length() == k) { + return k; + } + + // ward: 가장 많은 빈도수의 문자와 인덱스가 정확하게 나오지 않는 이슈가 있다. + int mx = 1; + int gMx = 1; + int index = 0; + char prev = s.charAt(0); + for (int i = 1; i < s.length(); i++) { + char cur = s.charAt(i); + + if (prev == cur) { + mx++; + } else { + // System.out.println("mx " + mx); + // System.out.println("gMx " + gMx); + if (mx > gMx) { + // System.out.println(i - 1); + gMx = mx; + index = i - 1; + } + + mx = 1; + prev = cur; + } + } + + if (mx > gMx) { + gMx = mx; + index = s.length() - 1; + } + + // k번 오른쪽으로 이동하며 가장 큰 문자를 치환. + char mostFreq = s.charAt(index); + char[] cArrR = s.toCharArray(); + char[] cArrL = s.toCharArray(); + + int cnt = 0; + int init = 1; + // System.out.println("index " + index); + // System.out.println("mostFreq " + mostFreq); + while (cnt <= k - 1) { + int targetIndex = index + init; + + // System.out.println("called " + targetIndex); + + if (targetIndex >= s.length()) { + break; + } + + if (cArrR[targetIndex] == mostFreq) { + init++; + continue; + } + + cArrR[targetIndex] = mostFreq; + init++; + cnt++; + } + + for (char anChar : cArrR) { + System.out.print(anChar); + } + System.out.println(); + + if (cnt < k) { + int startIndex = index - mx; // 맞느지 직접 확인해봐야함. + int temp = 1; + while (cnt <= k - 1) { + int targetIndex = startIndex - temp; + + if (targetIndex < 0) { + break; + } + + if (cArrR[targetIndex] == mostFreq) { + temp++; + continue; + } + + cArrR[targetIndex] = mostFreq; + temp++; + cnt++; + } + } + + // 위에서 사용한 cnt 변수 초기화 + cnt = 0; + init = 1; + if (index != 0) { + // k번 왼쪽으로 이동하며 가장 빈도높게 나왔던 문자를 치환. + while (cnt <= k - 1) { + int targetIndex = index - init; + + if (targetIndex < 0) { + break; + } + + if (cArrL[targetIndex] == mostFreq) { + init++; + continue; + } + + cArrL[targetIndex] = mostFreq; + init++; + cnt++; + } + } + + if (cnt < k) { + int temp = 1; + while (cnt <= k - 1) { + int targetIndex = temp + index; + + if (targetIndex >= s.length()) { + break; + } + + if (cArrL[targetIndex] == mostFreq) { + temp++; + continue; + } + + cArrL[targetIndex] = mostFreq; + temp++; + cnt++; + } + } + + for (char anChar : cArrL) { + System.out.print(anChar); + } + System.out.println(); + + // 왼쪽 오른쪽으로 치환된 문자열들에 대해서 각각 가장 연속된 문자열 길이 구하는 동작 수행하기 + int gMxR = 1; + int gMxL = 1; + int mxR = 1; + int mxL = 1; + int prevR = cArrR[0]; + int prevL = cArrL[0]; + for (int i = 1; i < s.length(); i++) { + char curR = cArrR[i]; + char curL = cArrL[i]; + + if (prevR == curR) { + mxR++; + } else { + gMxR = Math.max(gMxR, mxR); + mxR = 1; + prevR = curR; + } + + if (prevL == curL) { + mxL++; + } else { + gMxL = Math.max(gMxL, mxL); + mxL = 1; + prevL = curL; + } + } + + gMxR = Math.max(mxR, gMxR); + gMxL = Math.max(mxL, gMxL); + + return Math.max(gMxR, gMxL); + } +}