Caren
August 08, 2020
380

SE103 - Week 9, Session 2

August 08, 2020

Transcript

1. Week 9:
Dynamic Programming,
Continued!

2. - Fibonacci
- Knapsack
- Unbounded knapsack
- Palindromic Sequences
- Common Substrings
Common Patterns in DP

3. - Fibonacci
- Knapsack
- Unbounded knapsack
- Palindromic Sequences
- Common Substrings
Common Patterns in DP

4. Given a string, ﬁnd the length of its Longest
Palindromic 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

5. Given a string, ﬁnd the length of its Longest Palindromic Subsequence
(LPS). In a palindromic subsequence, elements read the same
backward and forward.
Example 1
Given: abdbca
Return: ??
Longest Palindromic Subsequence

6. Given a string, ﬁnd the length of its Longest Palindromic Subsequence
(LPS). In a palindromic subsequence, elements read the same
backward and forward.
Example 1
Given: abdbca
Return: 5 (abdba)
Longest Palindromic Subsequence

7. Given a string, ﬁnd the length of its Longest Palindromic 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

8. Given a string, ﬁnd the length of its Longest Palindromic 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

9. Given a string, ﬁnd the length of its Longest Palindromic 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

10. Given a string, ﬁnd the length of its Longest Palindromic 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

11. Given: cddpd
Return: 3 (ddd or dpd)
Intuitively…
Let’s have two pointers, one starting at the beginning and one starting
at the end
cddpd

Longest Palindromic Subsequence

12. Given: cddpd
Return: 3 (ddd or dpd)
Intuitively…
Let’s have 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

13. Given: cddpd
Return: 3 (ddd or dpd)
Intuitively…
Let’s have 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

14. Longest Palindromic Subsequence
cddpd

15. Longest Palindromic Subsequence
c != d
cddpd

16. Longest Palindromic Subsequence
c != d
cddpd
ddpd cddp

17. Longest Palindromic Subsequence
c != d
cddpd
ddpd cddp
d == d
count = 2

18. Longest Palindromic Subsequence
c != d
cddpd
ddpd cddp
c != p
d == d
count = 2

19. Longest Palindromic Subsequence
c != d
cddpd
ddpd cddp
c != p
d == d
count = 2
dp

20. Longest Palindromic Subsequence
c != d
cddpd
ddpd cddp
c != p
d == d
count = 2
dp
d != p
p d

21. Longest Palindromic Subsequence
c != d
cddpd
ddpd cddp
c != p
d == d
count = 2
dp
d != p
p d
p == p
count = 1
d == d
count = 1

22. Longest Palindromic Subsequence
c != d
cddpd
ddpd cddp
c != p
d == d
count = 2
dp
d != p
p d
p == p
count = 1
d == d
count = 1
2 + Max(1, 1) = 3

23. Longest Palindromic Subsequence
c != d
cddpd
ddpd cddp
c != 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: ??

24. Longest Palindromic Subsequence
c != d
cddpd
ddpd cddp
c != 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);

25. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1 2 3 4
0
0
1
2
3
4
starting index
c d d p d
0 1 2 3 4
ending index

26. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
length = 1

27. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1
1
1
1
1
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
length = 1

28. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1
1
1
1
1
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
length = 2

29. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1
1
1
1
1
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
length = 2
what substring is this?

30. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1
1
1
1
1
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
length = 2
“cd”

31. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1 1
1
1
1
1
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
length = 2
“cd”

32. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1 1
1
1
1
1
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
length = 2
“dd”

33. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1 1
1 2
1
1
1
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
length = 2
“dd”

34. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1 1
1 2
1 1
1
1
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
length = 2
“dp”

35. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1 1
1 2
1 1
1 1
1
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
length = 2
“pd”

36. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1 1
1 2
1 1
1 1
1
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
length = 3

37. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1 1
1 2
1 1
1 1
1
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
“cdd”
max of “cd,”
and “dd”

38. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1 1 2
1 2
1 1
1 1
1
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
“cdd”
max of “cd,”
and “dd”

39. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1 1 2
1 2 2
1 1
1 1
1
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
“ddp”
max of “dd,”
and “dp”

40. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1 1 2
1 2 2
1 1
1 1
1
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
“dpd”
max of “dp,”
and “pd”

41. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1 1 2
1 2 2
1 1
1 1
1
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
“dpd”
max of “dp,”
and “pd”
… 1?!?

42. Given: cddpd
Return: 3 (ddd or dpd)
Longest Palindromic Subsequence
1 1 2
1 2 2
1 1 3
1 1
1
1 2 3 4
0
0
1
2
3
4
starting index
ending index
c d d p d
0 1 2 3 4
“dpd”
If start == end,
2 + start[+1]end[-1]
(“p”)

43. // create dp[][] array
dp[i][i] = 1; // every length 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];

44. // create dp[][] array
dp[i][i] = 1; // every length 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

45. // create dp[][] array
dp[i][i] = 1; // every length 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

46. // create dp[][] array
dp[i][i] = 1; // every length 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

47. // create dp[][] array
dp[i][i] = 1; // every length 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

48. // create dp[][] array
dp[i][i] = 1; // every length 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

49. // create dp[][] array
dp[i][i] = 1; // every length 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

50. // create dp[][] array
dp[i][i] = 1; // every length 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];

51. // create dp[][] array
dp[i][i] = 1; // every length 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];

52. What did we learn?

53. - Solving it ‘naively’ ﬁrst helps come up with DP
approach
- Recursive -> bottom up approach
- Palindromic questions -> two pointers, one at start
and one at end
What did we learn?

54. 2 problems
30 minutes for each problem
Pick the person that has their birthday coming up
next!
Mock Interviews

55. How did it go??

56. - DP problems are hard, practice is key
- We didn’t cover DP + Binary Trees, would
recommend spending some time practicing that
- HackerRank
- More practice next week!
Before next session

57. Journey of Caren’s career

58. Interned at Dreamworks for two semesters

59. Interned at Dreamworks for two semesters
-> realized I didn’t like big companies

60. Interned at Dreamworks
-> realized I didn’t like big companies
Recruited a bunch senior year, failed a bunch of interviews

61. Interned at Dreamworks
-> realized I didn’t like big companies
Recruited a bunch senior year, failed a bunch of interviews
Got a full time offer at a ﬁnancial startup (75k) -> wasn’t really excited, but
wanted a job

62. Interned at Dreamworks
-> realized I didn’t like big companies
Recruited a bunch senior year, failed a bunch of interviews
Got a full time offer at a ﬁnancial 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)

63. Interned at Dreamworks
-> realized I didn’t like big companies
Recruited a bunch senior year, failed a bunch of interviews
Got a full time offer at a ﬁnancial 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)

64. Interned at Dreamworks
-> realized I didn’t like big companies
Recruited a bunch senior year, failed a bunch of interviews
Got a full time offer at a ﬁnancial 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

65. Got two full time offers at two different startups
- company A (110k)
- company B (105k)
- negotiated a bit: company A -> 110k, company B -> 115k + 15k sign
on bonus

66. Got two full time offers at two different startups
- 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

67. Got two full time offers at two different startups
- 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