Subsequence (LPS). In a palindromic subsequence, elements read the same backward and forward. A subsequence is a sequence that can be derived from another sequence by deleting some or no elements without changing the order of the remaining elements. Longest Palindromic Subsequence
Subsequence (LPS). In a palindromic subsequence, elements read the same backward and forward. Example 1 Given: abdbca Return: ?? Longest Palindromic Subsequence
Subsequence (LPS). In a palindromic subsequence, elements read the same backward and forward. Example 1 Given: abdbca Return: 5 (abdba) Longest Palindromic Subsequence
Subsequence (LPS). In a palindromic subsequence, elements read the same backward and forward. Example 1 Given: abdbca Return: 5 (abdba) Example 2 Given: cddpd Return: ?? Longest Palindromic Subsequence
Subsequence (LPS). In a palindromic subsequence, elements read the same backward and forward. Example 1 Given: abdbca Return: 5 (abdba) Example 2 Given: cddpd Return: 3 (ddd or dpd) Longest Palindromic Subsequence
Subsequence (LPS). In a palindromic subsequence, elements read the same backward and forward. Example 1 Given: abdbca Return: 5 (abdba) Example 2 Given: cddpd Return: 3 (ddd or dpd) Example 3 Given: abc Return: ?? Longest Palindromic Subsequence
Subsequence (LPS). In a palindromic subsequence, elements read the same backward and forward. Example 1 Given: abdbca Return: 5 (abdba) Example 2 Given: cddpd Return: 3 (ddd or dpd) Example 3 Given: abc Return: 1 (a or b or c) Longest Palindromic Subsequence
two pointers, one starting at the beginning and one starting at the end cddpd If the letters are the same - count of palindromic subsequence = 2 - recurively do this for the rest of the substring Longest Palindromic Subsequence
two pointers, one starting at the beginning and one starting at the end cddpd If the letters are the same - count of palindromic subsequence = 2 if letters are NOT the same - try advancing starting pointer cddpd - try advancing ending pointer cddpd Longest Palindromic Subsequence
!= p d == d count = 2 dp d != p p d p == p count = 1 d == d count = 1 2 + 1 = 3 if(startIndex == endIndex) return 1; // case 1: beginning and the end are the same if(st.charAt(startIndex) == st.charAt(endIndex)) return 2 + lpsLengthRecursive(st, startIndex+1, endIndex-1); // case 2: skip one element either from the beginning or the end int r1 = lpsLengthRecursive(startIndex+1, endIndex); int r2 = lpsLengthRecursive(startIndex, endIndex-1); return Math.max(r1, r2); Run time: ??
!= p d == d count = 2 dp d != p p d p == p count = 1 d == d count = 1 2 + 1 = 3 if(startIndex == endIndex) return 1; // case 1: beginning and the end are the same if(st.charAt(startIndex) == st.charAt(endIndex)) return 2 + lpsLengthRecursive(st, startIndex+1, endIndex-1); // case 2: skip one element either from the beginning or the end int r1 = lpsLengthRecursive(startIndex+1, endIndex); int r2 = lpsLengthRecursive(startIndex, endIndex-1); return Math.max(r1, r2); Run time: 2 ^ n if(startIndex == endIndex) return 1; // case 1: beginning and the end are the same if(st.charAt(startIndex) == st.charAt(endIndex)) return 2 + lpsLengthRecursive(st, startIndex+1, endIndex-1); // case 2: skip one element either from the beginning or the end int r1 = lpsLengthRecursive(startIndex+1, endIndex); int r2 = lpsLengthRecursive(startIndex, endIndex-1); return Math.max(r1, r2);
1 substring for (int startIndex = s.length() - 1; startIndex >= 0; startIndex--) { for (int endIndex = startIndex + 1; endIndex < s.length(); endIndex++) { // case 1: letter at the beginning and the end are the same if (s.charAt(startIndex) == s.charAt(endIndex)) { dp[startIndex][endIndex] = 2 + dp[startIndex + 1][endIndex - 1]; } else { // case 2: skip one element either from the beginning or the end dp[startIndex][endIndex] = Math.max( dp[startIndex + 1][endIndex], dp[startIndex][endIndex - 1]); } } } return dp[0][st.length() - 1];
1 substring for (int startIndex = s.length() - 1; startIndex >= 0; startIndex--) { for (int endIndex = startIndex + 1; endIndex < s.length(); endIndex++) { // case 1: letter at the beginning and the end are the same if (s.charAt(startIndex) == s.charAt(endIndex)) { dp[startIndex][endIndex] = 2 + dp[startIndex + 1][endIndex - 1]; } else { // case 2: skip one element either from the beginning or the end dp[startIndex][endIndex] = Math.max( dp[startIndex + 1][endIndex], dp[startIndex][endIndex - 1]); } } } return dp[0][st.length() - 1]; start end
1 substring for (int startIndex = s.length() - 1; startIndex >= 0; startIndex--) { for (int endIndex = startIndex + 1; endIndex < s.length(); endIndex++) { // case 1: letter at the beginning and the end are the same if (s.charAt(startIndex) == s.charAt(endIndex)) { dp[startIndex][endIndex] = 2 + dp[startIndex + 1][endIndex - 1]; } else { // case 2: skip one element either from the beginning or the end dp[startIndex][endIndex] = Math.max( dp[startIndex + 1][endIndex], dp[startIndex][endIndex - 1]); } } } return dp[0][st.length() - 1]; start end
1 substring for (int startIndex = s.length() - 1; startIndex >= 0; startIndex--) { for (int endIndex = startIndex + 1; endIndex < s.length(); endIndex++) { // case 1: letter at the beginning and the end are the same if (s.charAt(startIndex) == s.charAt(endIndex)) { dp[startIndex][endIndex] = 2 + dp[startIndex + 1][endIndex - 1]; } else { // case 2: skip one element either from the beginning or the end dp[startIndex][endIndex] = Math.max( dp[startIndex + 1][endIndex], dp[startIndex][endIndex - 1]); } } } return dp[0][st.length() - 1]; start end
1 substring for (int startIndex = s.length() - 1; startIndex >= 0; startIndex--) { for (int endIndex = startIndex + 1; endIndex < s.length(); endIndex++) { // case 1: letter at the beginning and the end are the same if (s.charAt(startIndex) == s.charAt(endIndex)) { dp[startIndex][endIndex] = 2 + dp[startIndex + 1][endIndex - 1]; } else { // case 2: skip one element either from the beginning or the end dp[startIndex][endIndex] = Math.max( dp[startIndex + 1][endIndex], dp[startIndex][endIndex - 1]); } } } return dp[0][st.length() - 1]; start end
1 substring for (int startIndex = s.length() - 1; startIndex >= 0; startIndex--) { for (int endIndex = startIndex + 1; endIndex < s.length(); endIndex++) { // case 1: letter at the beginning and the end are the same if (s.charAt(startIndex) == s.charAt(endIndex)) { dp[startIndex][endIndex] = 2 + dp[startIndex + 1][endIndex - 1]; } else { // case 2: skip one element either from the beginning or the end dp[startIndex][endIndex] = Math.max( dp[startIndex + 1][endIndex], dp[startIndex][endIndex - 1]); } } } return dp[0][st.length() - 1]; start end
1 substring for (int startIndex = s.length() - 1; startIndex >= 0; startIndex--) { for (int endIndex = startIndex + 1; endIndex < s.length(); endIndex++) { // case 1: letter at the beginning and the end are the same if (s.charAt(startIndex) == s.charAt(endIndex)) { dp[startIndex][endIndex] = 2 + dp[startIndex + 1][endIndex - 1]; } else { // case 2: skip one element either from the beginning or the end dp[startIndex][endIndex] = Math.max( dp[startIndex + 1][endIndex], dp[startIndex][endIndex - 1]); } } } return dp[0][st.length() - 1]; start end
1 substring for (int startIndex = s.length() - 1; startIndex >= 0; startIndex--) { for (int endIndex = startIndex + 1; endIndex < s.length(); endIndex++) { // case 1: letter at the beginning and the end are the same if (s.charAt(startIndex) == s.charAt(endIndex)) { dp[startIndex][endIndex] = 2 + dp[startIndex + 1][endIndex - 1]; } else { // case 2: skip one element either from the beginning or the end dp[startIndex][endIndex] = Math.max( dp[startIndex + 1][endIndex], dp[startIndex][endIndex - 1]); } } } return dp[0][st.length() - 1];
1 substring for (int startIndex = s.length() - 1; startIndex >= 0; startIndex--) { for (int endIndex = startIndex + 1; endIndex < s.length(); endIndex++) { // case 1: letter at the beginning and the end are the same if (s.charAt(startIndex) == s.charAt(endIndex)) { dp[startIndex][endIndex] = 2 + dp[startIndex + 1][endIndex - 1]; } else { // case 2: skip one element either from the beginning or the end dp[startIndex][endIndex] = Math.max( dp[startIndex + 1][endIndex], dp[startIndex][endIndex - 1]); } } } return dp[0][st.length() - 1];
companies Recruited a bunch senior year, failed a bunch of interviews Got a full time offer at a financial startup (75k) -> wasn’t really excited, but wanted a job
companies Recruited a bunch senior year, failed a bunch of interviews Got a full time offer at a financial startup (75k) -> wasn’t really excited, but wanted a job Found an internship at a startup (7k / month) Converted to full time after 3 months (90k) -> got a raise after 6 months (100k)
companies Recruited a bunch senior year, failed a bunch of interviews Got a full time offer at a financial startup (75k) -> wasn’t really excited, but wanted a job Found an internship at a startup (7k / month) Converted to full time after 3 months (90k) -> got a raise after 6 months (100k) One year later… Wanted to feel more challenged at my job -> took a CodePath Android class (8 weeks)
companies Recruited a bunch senior year, failed a bunch of interviews Got a full time offer at a financial startup (75k) -> wasn’t really excited, but wanted a job Found an internship at a startup (7k / month) Converted to full time after 3 months (90k) -> got a raise after 6 months (100k) One year later… Wanted to feel more challenged at my job -> took a CodePath Android class (8 weeks) Recruited for Android jobs -> failed a bunch
- company A (110k) - company B (105k) - negotiated a bit: company A -> 110k, company B -> 115k + 15k sign on bonus 1.5 years later -> Felt like I wasn’t learning much anymore -> looked for jobs at hardware companies
- company A (110k) - company B (105k) - negotiated a bit: company A -> 110k, company B -> 115k + 15k sign on bonus 1.5 years later -> Felt like I wasn’t learning much anymore -> looked for jobs at hardware companies 2 years later -> Thought about starting to save more money -> Recruited at big companies