Skip to content

Commit

Permalink
add 1048 java
Browse files Browse the repository at this point in the history
  • Loading branch information
yennanliu committed Oct 20, 2024
1 parent dd875b4 commit 5ffe63c
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 11 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,7 @@
518| [Coin Change 2](https://leetcode.com/problems/coin-change-2/) | [Python](./leetcode_python/Dynamic_Programming/coin_change_2.py) | _O(logn)_ | _O(1)_ | Medium | `dp basic`,`good trick`,check `# 322 Coin Change`,`dp`, `google`, `fb`| AGAIN******** (4)
494| [Target Sum](https://leetcode.com/problems/target-sum/) | [Python](./leetcode_python/Dynamic_Programming/target-sum.py) | _O(logn)_ | _O(1)_ | Medium |dp basic, `dp`, `fb`| AGAIN***** (1)
1000| [ Minimum Cost to Merge Stones](https://leetcode.com/problems/minimum-cost-to-merge-stones/) | [Python](./leetcode_python/Dynamic_Programming/minimum-cost-to-merge-stones.py) | _O(logn)_ | _O(1)_ | Medium |dp, amazon| AGAIN (not start)
1048| [Longest String Chain](https://leetcode.com/problems/longest-string-chain/description/) | [Java](./leetcode_java/src/main/java/LeetCodeJava/DynamicProgramming/LongestStringChain.java) | _O(logn)_ | _O(1)_ | Medium |dp, google| AGAIN (not start)
1143| [Longest Common Subsequence](https://leetcode.com/problems/longest-common-subsequence/) | [Python](./leetcode_python/Dynamic_Programming/longest-common-subsequence.py) | _O(logn)_ | _O(1)_ | Medium |Curated Top 75, Memoization, dp, amazon, karat| AGAIN*** (2) (not start)
1312| [Minimum Insertion Steps to Make a String Palindrome](https://leetcode.com/problems/minimum-insertion-steps-to-make-a-string-palindrome/) | [Python](./leetcode_python/Dynamic_Programming/minimum-insertion-steps-to-make-a-string-palindrome.py) | _O(logn)_ | _O(1)_ | Hard |dp, amazon| AGAIN (not start)
1335| [Minimum Difficulty of a Job Schedule](https://leetcode.com/problems/minimum-difficulty-of-a-job-schedule/) | [Python](./leetcode_python/Dynamic_Programming/minimum-difficulty-of-a-job-schedule.py) | _O(logn)_ | _O(1)_ | Medium |`dp`, `amazon`| not start
Expand Down
2 changes: 1 addition & 1 deletion data/progress.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
20241020: 163
20241020: 163,1048
20241019: 298,729
20241018: 1146
20241014: 737
Expand Down
22 changes: 12 additions & 10 deletions data/to_review.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
2024-12-14 -> ['163,1048']
2024-12-13 -> ['298,729']
2024-12-12 -> ['1146']
2024-12-08 -> ['737']
Expand All @@ -9,7 +10,7 @@
2024-11-27 -> ['524,221,889']
2024-11-26 -> ['743,889']
2024-11-25 -> ['837']
2024-11-23 -> ['981']
2024-11-23 -> ['163,1048', '981']
2024-11-22 -> ['298,729', '1087']
2024-11-21 -> ['1146']
2024-11-20 -> ['939']
Expand All @@ -20,24 +21,25 @@
2024-11-14 -> ['528,334']
2024-11-12 -> ['1145', '753']
2024-11-11 -> ['727']
2024-11-10 -> ['163,1048']
2024-11-09 -> ['298,729', '1145,1219']
2024-11-08 -> ['1146']
2024-11-06 -> ['524,221,889']
2024-11-05 -> ['743,889']
2024-11-04 -> ['737', '837', '659']
2024-11-03 -> ['686,734,737', '801,552']
2024-11-02 -> ['353', '981', '1057,1066,1110']
2024-11-02 -> ['163,1048', '353', '981', '1057,1066,1110']
2024-11-01 -> ['298,729', '528,334', '1087']
2024-10-31 -> ['1146']
2024-10-30 -> ['1145', '939']
2024-10-28 -> ['430']
2024-10-28 -> ['163,1048', '430']
2024-10-27 -> ['298,729', '737', '1145,1219', '363']
2024-10-26 -> ['1146', '686,734,737', '1032,844,1011']
2024-10-25 -> ['353', '947', '1110, 1055']
2024-10-25 -> ['163,1048', '353', '947', '1110, 1055']
2024-10-24 -> ['298,729', '528,334', '524,221,889']
2024-10-23 -> ['1146', '743,889']
2024-10-22 -> ['298,729', '737', '1145', '837', '753']
2024-10-21 -> ['298,729', '1146', '686,734,737', '727']
2024-10-23 -> ['163,1048', '1146', '743,889']
2024-10-22 -> ['163,1048', '298,729', '737', '1145', '837', '753']
2024-10-21 -> ['163,1048', '298,729', '1146', '686,734,737', '727']
2024-10-20 -> ['298,729', '1146', '353', '981']
2024-10-19 -> ['1146', '737', '528,334', '1145,1219', '1087']
2024-10-18 -> ['686,734,737', '359,1057,1055(todo)']
Expand Down Expand Up @@ -829,12 +831,12 @@
2020-07-14 -> ['130', '066,271', '711,046,126,127']
2020-07-13 -> ['346,686', '738', '063,064,120,0146']
2020-07-12 -> ['210,261', '396', '675,297,138']
2020-07-11 -> ['163', '066,271', '361,393,133,207', '482,127,102,107']
2020-07-11 -> ['066,271', '163', '361,393,133,207', '482,127,102,107']
2020-07-10 -> ['734,737', '388', '836,860,863']
2020-07-09 -> ['066,271', '694']
2020-07-08 -> ['163', '066,271', '646', '663']
2020-07-08 -> ['066,271', '163', '646', '663']
2020-07-07 -> ['066,271', '210,261', '298', '776', '661,662', '703,787,819']
2020-07-06 -> ['163', '130', '361,393,133,207', '669,682,739,763']
2020-07-06 -> ['130', '163', '361,393,133,207', '669,682,739,763']
2020-07-05 -> ['163', '734,737', '346,686', '771,775', '701,450', '642,652,657']
2020-07-04 -> ['163', '210,261', '640,645', '545,617,628']
2020-07-03 -> ['361,393,133,207', '482,127,102,107', '762', '606,459']
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package LeetCodeJava.DynamicProgramming;

// https://leetcode.com/problems/longest-string-chain/description/

import java.util.*;

/**
*1048. Longest String Chain
* Medium
* Topics
* Companies
* Hint
* You are given an array of words where each word consists of lowercase English letters.
*
* wordA is a predecessor of wordB if and only if we can insert exactly one letter anywhere in wordA without changing the order of the other characters to make it equal to wordB.
*
* For example, "abc" is a predecessor of "abac", while "cba" is not a predecessor of "bcad".
* A word chain is a sequence of words [word1, word2, ..., wordk] with k >= 1, where word1 is a predecessor of word2, word2 is a predecessor of word3, and so on. A single word is trivially a word chain with k == 1.
*
* Return the length of the longest possible word chain with words chosen from the given list of words.
*
* Example 1:
*
* Input: words = ["a","b","ba","bca","bda","bdca"]
* Output: 4
* Explanation: One of the longest word chains is ["a","ba","bda","bdca"].
* Example 2:
*
* Input: words = ["xbc","pcxbcf","xb","cxbc","pcxbc"]
* Output: 5
* Explanation: All the words can be put in a word chain ["xb", "xbc", "cxbc", "pcxbc", "pcxbcf"].
* Example 3:
*
* Input: words = ["abcd","dbqca"]
* Output: 1
* Explanation: The trivial word chain ["abcd"] is one of the longest word chains.
* ["abcd","dbqca"] is not a valid word chain because the ordering of the letters is changed.
*
*
* Constraints:
*
* 1 <= words.length <= 1000
* 1 <= words[i].length <= 16
* words[i] only consists of lowercase English letters.
*
*/
public class LongestStringChain {

// V0
// TODO : implement
// public int longestStrChain(String[] words) {
// }

// V1-1
// IDEA : DFS + Memoization | Increasing Word Length:
// https://leetcode.com/problems/longest-string-chain/solutions/2153004/explaining-three-approaches-java/
private Map<Integer, List<String>> wordLengthMap;
private Map<String, Integer> memo;

public int longestStrChain_1(String[] words) {
// store each word with its corresponding length
wordLengthMap = new HashMap<>();
for (String word: words) {
wordLengthMap.putIfAbsent(word.length(), new ArrayList<>());
wordLengthMap.get(word.length()).add(word);
}

int maxPath = 1;
memo = new HashMap<>();
for (String word: words)
maxPath = Math.max(maxPath, dfs(word));

return maxPath;
}

private int dfs(String word) {
if (!wordLengthMap.containsKey(word.length() + 1)) return 1; // if there are no words of the next length, we're done with this path.
if (memo.containsKey(word)) return memo.get(word); // if we're computed this word before, return the result.

int maxPath = 0;
// for each word, find all words which are 1 letter longer and see if they are valid successors.
List<String> nextWords = wordLengthMap.get(word.length() + 1);
for (String nextWord: nextWords)
if (isOneOff(word, nextWord))
maxPath = Math.max(maxPath, dfs(nextWord));

memo.put(word, maxPath + 1); // store our result
return memo.get(word);
}

// returns true if two strings differ by no more than 1 letter
private boolean isOneOff(String a, String b) {
int count = 0;
for (int i=0, j=0; i<b.length() && j<a.length() && count <= 1; i++) {
if (a.charAt(j) != b.charAt(i)) count++;
else j++;
}
return count <= 1;
}


// V1-2
// IDEA : DFS + Memoization | Decreasing Word Length:
// https://leetcode.com/problems/longest-string-chain/solutions/2153004/explaining-three-approaches-java/
// private Set<String> wordDict;
// private Map<String, Integer> memo;
//
// public int longestStrChain(String[] words) {
// wordDict = new HashSet<>();
// Collections.addAll(wordDict, words); // adding all words to a set for constant look-up
//
// int maxPath = 1;
// memo = new HashMap<>();
// for (String word: words)
// maxPath = Math.max(maxPath, dfs(word));
//
// return maxPath;
// }
//
// private int dfs(String word) {
// if (memo.containsKey(word)) return memo.get(word); // if we're computed this word before, return the result.
//
// StringBuilder sb = new StringBuilder(word);
// int maxPath = 0;
// // delete each character, check if that's a valid word in the set, add the character back and continue
// for (int i=0; i<word.length(); i++) {
// sb.deleteCharAt(i);
// String prevWord = sb.toString();
// if (wordDict.contains(prevWord))
// maxPath = Math.max(maxPath, dfs(prevWord));
// sb.insert(i, word.charAt(i));
// }
//
// memo.put(word, maxPath + 1); // store the result
// return memo.get(word);
// }


// V1-3
// IDEA : DP | Decreasing Word Length:
// https://leetcode.com/problems/longest-string-chain/solutions/2153004/explaining-three-approaches-java/
public int longestStrChain_1_3(String[] words) {
Arrays.sort(words, (String a, String b) -> a.length() - b.length()); // sort by length
Map<String, Integer> dp = new HashMap<>();

int maxPath = 1;
// same idea behind the previous approach but performed iteratively.
for (String word: words) {
int currLength = 1;
StringBuilder sb = new StringBuilder(word);
for (int i=0; i<word.length(); i++) {
sb.deleteCharAt(i);
String prevWord = sb.toString();
currLength = Math.max(currLength, dp.getOrDefault(prevWord, 0) + 1);
sb.insert(i, word.charAt(i));
}
dp.put(word, currLength);
maxPath = Math.max(maxPath, currLength);
}

return maxPath;
}

// V2

}
7 changes: 7 additions & 0 deletions leetcode_java/src/main/java/dev/workspace5.java
Original file line number Diff line number Diff line change
Expand Up @@ -1849,6 +1849,13 @@ else if (nums[i] != nums[i-1]){
return res;
}

// LC 1048
// 4.19 pm - 4.30 pm
// https://leetcode.com/problems/longest-string-chain/
public int longestStrChain(String[] words) {
return 0;
}


}

Expand Down

0 comments on commit 5ffe63c

Please sign in to comment.