diff --git a/combination-sum/ready-oun.java b/combination-sum/ready-oun.java new file mode 100644 index 000000000..5ddcc438a --- /dev/null +++ b/combination-sum/ready-oun.java @@ -0,0 +1,53 @@ +import java.util.*; +class Solution { + public List> combinationSum(int[] candidates, int target) { + List> result = new ArrayList<>(); + List temp = new ArrayList<>(); + + backtrack(candidates, target, 0, temp, result); + return result; + } + private void backtrack(int[] candidates, int target, int start, List temp, List> result) { + if (target < 0) return; + if (target == 0) { + result.add(new ArrayList<>(temp)); // deep copy + return; + } + + for (int i = start; i < candidates.length; i++) { + temp.add(candidates[i]); + backtrack(candidates, target - candidates[i], i, temp, result); + temp.remove(temp.size() -1); + } + + } +} + +/** +Return all unique combinations where the candidate num sum to target +- each num in cand[] can be used unlimited times +- order of num in comb does NOT matter + +1. use backtracking to explore all possible comb +2. backtrack, if current sum > target +3. save comb, if current sum == target +4. avoid dupl -> only consider num from crnt idx onward (no going back) + +Time: O(2^target) +Space: O(target) + +Learned: Backtracking vs DFS +- DFS: search all paths deeply (no conditions, no rollback). +- Backtracking = DFS + decision making + undo step. +Explore, prune (if invalid), save (if valid), then undo last choice. + + for (선택 가능한 숫자 하나씩) { + 선택하고 + target 줄이고 (목표 가까워짐) + 재귀 호출로 다음 선택 + 실패하거나 성공하면 되돌리기 (백트래킹) + } + +DFS just visits everything, +Backtracking visits only what’s promising — and turns back if not! + */ diff --git a/number-of-1-bits/ready-oun.java b/number-of-1-bits/ready-oun.java new file mode 100644 index 000000000..f3396a2e4 --- /dev/null +++ b/number-of-1-bits/ready-oun.java @@ -0,0 +1,31 @@ +class Solution { + public int hammingWeight(int n) { + int count = 0; + + while (n != 0) { + if ((n & 1) == 1) { + count++; + } + n = n >>> 1; + } + + return count; + } +} + +/** +Time: O(1) – max 32 iterations (fixed bit size) +Space: O(1) + +How it works: Shift each bit → Check → Count → Shift again + 1. Shift each bit of n to the right + 2. Check if the last bit is 1 using n & 1 + 3. If it is, increment the count + 4. Shift n to the right using n = n >>> 1 + +Learned: + (n & 1) isolates the least significant bit (LSB) to check if it’s 1 + >> : Arithmetic shift (fills in sign bit, so infinite loop for negatives) + >>> : Logical shift (always fills with 0, safe for negatives) + Java evaluates == before &, so use parentheses to control the order + */ diff --git a/valid-palindrome/ready-oun.java b/valid-palindrome/ready-oun.java new file mode 100644 index 000000000..2eea9e3a7 --- /dev/null +++ b/valid-palindrome/ready-oun.java @@ -0,0 +1,48 @@ +class Solution { + public boolean isPalindrome(String s) { + StringBuilder cleaned = new StringBuilder(); + + for (char c : s.toCharArray()) { + if (Character.isLetterOrDigit(c)) { + cleaned.append(Character.toLowerCase(c)); + } + } + + int left = 0; + int right = cleaned.length() - 1; + while (left < right) { + // Fail fast: return false as soon as a mismatch is found + if (cleaned.charAt(left) != cleaned.charAt(right)) { + return false; + } + left++; + right--; + } + + return true; + } +} + +/** +converting all uppercase letters into lowercase letters +removing all non-alphanumeric char + +1. cleaning + 0. str -> char with for-each loop + 1. check char if isLetterOrDigit + 2. make char to LowerCase + * Character Class static method +2. two ptrs comparison while left < right + s[i] == s[n - 1 - i] + +- Time: O(n) + + /** REMEMBER +1. length vs length() + +arr.length => field +String(Builder).length() => method + +2. “fail fast” approach: +As soon as we detect something wrong, we exit early. + */