From 6991d1c2c91639272f2be79666d55e0d0ade15e9 Mon Sep 17 00:00:00 2001 From: Shukan Date: Sat, 11 Oct 2025 18:02:43 -0700 Subject: [PATCH 1/3] Greedy-2 --- EditDistance.java | 42 ++++++++++++++++++++++++++++++++ PartitionLabels.java | 30 +++++++++++++++++++++++ RegularExpressionMatching.java | 44 ++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 EditDistance.java create mode 100644 PartitionLabels.java create mode 100644 RegularExpressionMatching.java diff --git a/EditDistance.java b/EditDistance.java new file mode 100644 index 0000000..eb36631 --- /dev/null +++ b/EditDistance.java @@ -0,0 +1,42 @@ +/** + * Approach: Use dynamic programming to compute the minimum edit distance between two words. + * Solution: Build a DP table where dp[i][j] represents the min operations to convert first i chars of word1 to first j chars of word2. + * Transition: If chars match, take dp[i-1][j-1]; else take min of insert, delete, replace + 1. + */ +public class EditDistance { + public int minDistance(String word1, String word2) { + int word1Length = word1.length(); + int word2Length = word2.length(); + + if (word1Length == 0) { + return word2Length; + } + if (word2Length == 0) { + return word1Length; + } + + int dp[][] = new int[word1Length + 1][word2Length + 1]; + + for (int word1Index = 1; word1Index <= word1Length; word1Index++) { + dp[word1Index][0] = word1Index; + } + + for (int word2Index = 1; word2Index <= word2Length; word2Index++) { + dp[0][word2Index] = word2Index; + } + + for (int word1Index = 1; word1Index <= word1Length; word1Index++) { + for (int word2Index = 1; word2Index <= word2Length; word2Index++) { + if (word2.charAt(word2Index - 1) == word1.charAt(word1Index - 1)) { + dp[word1Index][word2Index] = dp[word1Index - 1][word2Index - 1]; + } else { + dp[word1Index][word2Index] = Math.min( + dp[word1Index - 1][word2Index], + Math.min(dp[word1Index][word2Index - 1], dp[word1Index - 1][word2Index - 1])) + 1; + } + } + } + + return dp[word1Length][word2Length]; + } +} diff --git a/PartitionLabels.java b/PartitionLabels.java new file mode 100644 index 0000000..a9c9dc6 --- /dev/null +++ b/PartitionLabels.java @@ -0,0 +1,30 @@ +/** + * Approach: Use a HashMap to store the last index of each character to determine partition boundaries. + * Solution: Iterate through the string, updating the current partition end to the farthest last index seen. + * When the current index equals the partition end, close the partition and record its length. + */ +public class PartitionLabels { + public List partitionLabels(String s) { + HashMap hmap = new HashMap<>(); + + for(int i = 0; i < s.length() ;i++) { + char c = s.charAt(i); + hmap.put(c,i); + } + + List result = new ArrayList<>(); + + int start = 0; + int end = 0; + + for(int i = 0; i < s.length() ; i++) { + char c = s.charAt(i); + end = Math.max(end, hmap.get(c)); + if(i == end) { + result.add(end-start+1); + start = i+1; + } + } + return result; + } +} \ No newline at end of file diff --git a/RegularExpressionMatching.java b/RegularExpressionMatching.java new file mode 100644 index 0000000..1895fb4 --- /dev/null +++ b/RegularExpressionMatching.java @@ -0,0 +1,44 @@ +/** + * Approach: Use dynamic programming to determine if string s matches pattern p with '.' and '*'. + * Solution: dp[i][j] represents if first i chars of s match first j chars of p; handle '*' by zero or multiple preceding elements. + * Transition: If chars match or '.', take dp[i-1][j-1]; if '*', combine zero or multiple occurrence cases. + */ + +public class RegularExpressionMatching { + public boolean isMatch(String s, String p) { + int m = s.length(); + int n = p.length(); + + boolean[][] dp = new boolean[m + 1][n + 1]; + + dp[0][0] = true; + + for (int j = 1; j <= n; j++) { + char pChar = p.charAt(j - 1); + if (pChar == '*') { + dp[0][j] = dp[0][j - 2]; + + } + } + + for (int i = 1; i <= m; i++) { + for (int j = 1; j <= n; j++) { + char pChar = p.charAt(j - 1); + if (pChar == '*') { + if (p.charAt(j - 2) == s.charAt(i - 1) || p.charAt(j-2) == '.') { + dp[i][j] = dp[i][j - 2] || dp[i - 1][j]; + } else { + dp[i][j] = dp[i][j - 2]; + } + } else { + if(pChar == s.charAt(i-1)) { + dp[i][j] = dp[i-1][j-1]; + } + } + + } + + } + + } +} From 127668deecc22c09c906ba4c4dd5ad8c1ffc350a Mon Sep 17 00:00:00 2001 From: Shukan Date: Sat, 11 Oct 2025 18:05:46 -0700 Subject: [PATCH 2/3] updated solution --- QueueReconstructionByHeight.java | 31 ++++++++++++++++++++++ RegularExpressionMatching.java | 44 -------------------------------- 2 files changed, 31 insertions(+), 44 deletions(-) create mode 100644 QueueReconstructionByHeight.java delete mode 100644 RegularExpressionMatching.java diff --git a/QueueReconstructionByHeight.java b/QueueReconstructionByHeight.java new file mode 100644 index 0000000..77ecc5f --- /dev/null +++ b/QueueReconstructionByHeight.java @@ -0,0 +1,31 @@ +/** + * Approach: Sort people by height in descending order; if heights are equal, sort by k value ascending. + * Solution: Insert each person into a list at the index equal to their k value, maintaining relative order. + * This ensures each person has exactly k taller or equal people in front when reconstruction is complete. + */ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class QueueReconstructionByHeight { + class Solution { + public int[][] reconstructQueue(int[][] people) { + Arrays.sort(people, (a,b) -> { + + if(a[0] == b [0]) { + return a[1] - b[1]; + } + + return b[0] - a[0]; + }); + + List result = new ArrayList<>(); + + for(int[] p : people) { + result.add(p[1],p); + } + + return result.toArray(new int[0][0]); + } +} +} diff --git a/RegularExpressionMatching.java b/RegularExpressionMatching.java deleted file mode 100644 index 1895fb4..0000000 --- a/RegularExpressionMatching.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Approach: Use dynamic programming to determine if string s matches pattern p with '.' and '*'. - * Solution: dp[i][j] represents if first i chars of s match first j chars of p; handle '*' by zero or multiple preceding elements. - * Transition: If chars match or '.', take dp[i-1][j-1]; if '*', combine zero or multiple occurrence cases. - */ - -public class RegularExpressionMatching { - public boolean isMatch(String s, String p) { - int m = s.length(); - int n = p.length(); - - boolean[][] dp = new boolean[m + 1][n + 1]; - - dp[0][0] = true; - - for (int j = 1; j <= n; j++) { - char pChar = p.charAt(j - 1); - if (pChar == '*') { - dp[0][j] = dp[0][j - 2]; - - } - } - - for (int i = 1; i <= m; i++) { - for (int j = 1; j <= n; j++) { - char pChar = p.charAt(j - 1); - if (pChar == '*') { - if (p.charAt(j - 2) == s.charAt(i - 1) || p.charAt(j-2) == '.') { - dp[i][j] = dp[i][j - 2] || dp[i - 1][j]; - } else { - dp[i][j] = dp[i][j - 2]; - } - } else { - if(pChar == s.charAt(i-1)) { - dp[i][j] = dp[i-1][j-1]; - } - } - - } - - } - - } -} From a260ad91af38c1e27fc75d62e81ff44911a5b5aa Mon Sep 17 00:00:00 2001 From: Shukan Date: Sat, 11 Oct 2025 18:09:00 -0700 Subject: [PATCH 3/3] updated solutions --- EditDistance.java | 42 ------------------------------------------ TaskScheduler.java | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 42 deletions(-) delete mode 100644 EditDistance.java create mode 100644 TaskScheduler.java diff --git a/EditDistance.java b/EditDistance.java deleted file mode 100644 index eb36631..0000000 --- a/EditDistance.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Approach: Use dynamic programming to compute the minimum edit distance between two words. - * Solution: Build a DP table where dp[i][j] represents the min operations to convert first i chars of word1 to first j chars of word2. - * Transition: If chars match, take dp[i-1][j-1]; else take min of insert, delete, replace + 1. - */ -public class EditDistance { - public int minDistance(String word1, String word2) { - int word1Length = word1.length(); - int word2Length = word2.length(); - - if (word1Length == 0) { - return word2Length; - } - if (word2Length == 0) { - return word1Length; - } - - int dp[][] = new int[word1Length + 1][word2Length + 1]; - - for (int word1Index = 1; word1Index <= word1Length; word1Index++) { - dp[word1Index][0] = word1Index; - } - - for (int word2Index = 1; word2Index <= word2Length; word2Index++) { - dp[0][word2Index] = word2Index; - } - - for (int word1Index = 1; word1Index <= word1Length; word1Index++) { - for (int word2Index = 1; word2Index <= word2Length; word2Index++) { - if (word2.charAt(word2Index - 1) == word1.charAt(word1Index - 1)) { - dp[word1Index][word2Index] = dp[word1Index - 1][word2Index - 1]; - } else { - dp[word1Index][word2Index] = Math.min( - dp[word1Index - 1][word2Index], - Math.min(dp[word1Index][word2Index - 1], dp[word1Index - 1][word2Index - 1])) + 1; - } - } - } - - return dp[word1Length][word2Length]; - } -} diff --git a/TaskScheduler.java b/TaskScheduler.java new file mode 100644 index 0000000..908c142 --- /dev/null +++ b/TaskScheduler.java @@ -0,0 +1,41 @@ +/** + * Approach: Use a max-heap to schedule the most frequent tasks first while respecting cooldowns using a queue. + * Solution: Pop tasks from the heap, execute them, and push them into a cooldown queue with the next valid time. + * Repeat until both heap and queue are empty, tracking total time to execute all tasks. + */ +public class TaskScheduler { + public int leastInterval(char[] tasks, int n) { + int[] freqMap = new int[26]; + + for (char ch : tasks) { + freqMap[ch - 'A']++; + } + + PriorityQueue maxHeap = new PriorityQueue<>((a, b) -> b - a); + for (int i = 0; i < 26; i++) { + if (freqMap[i] > 0) { + maxHeap.offer(freqMap[i]); + } + } + Deque queue = new LinkedList<>(); // count, time + int time = 0; + + while (!maxHeap.isEmpty() || !queue.isEmpty()) { + time++; + + if (!maxHeap.isEmpty()) { + int currentCount = maxHeap.poll() - 1; + if (currentCount > 0) { + queue.add(new int[] {currentCount, time + n }); + } + } + if (!queue.isEmpty() && queue.peekFirst()[1] == time) { + int[] elementEligibleForMaxHeap = queue.removeFirst(); + maxHeap.offer(elementEligibleForMaxHeap[0]); + } + } + + return time; + + } +} \ No newline at end of file