Press "Enter" to skip to content

Posts published in “Dynamic Programming”

花花酱 LeetCode DP Summary 动态规划总结

Summary: Input size / sub-problem size / sub-problem complexity / time complexity / space complexity

Category 1.1

Template

 

Summary and slides

花花酱 LeetCode 931. Minimum Falling Path Sum

Problem

Given a square array of integers A, we want the minimum sum of a falling path through A.

A falling path starts at any element in the first row, and chooses one element from each row.  The next row’s choice must be in a column that is different from the previous row’s column by at most one.

 

Example 1:

Input: [[1,2,3],[4,5,6],[7,8,9]]
Output: 12
Explanation: 
The possible falling paths are:
  • [1,4,7], [1,4,8], [1,5,7], [1,5,8], [1,5,9]
  • [2,4,7], [2,4,8], [2,5,7], [2,5,8], [2,5,9], [2,6,8], [2,6,9]
  • [3,5,7], [3,5,8], [3,5,9], [3,6,8], [3,6,9]

The falling path with the smallest sum is [1,4,7], so the answer is 12.

Note:

  1. 1 <= A.length == A[0].length <= 100
  2. -100 <= A[i][j] <= 100

Solution: DP

Time complexity: O(mn)

Space complexity: O(mn)

C++

C++/in place

花花酱 LeetCode 926. Flip String to Monotone Increasing

Problem

A string of '0's and '1's is monotone increasing if it consists of some number of '0's (possibly 0), followed by some number of '1's (also possibly 0.)

We are given a string S of '0's and '1's, and we may flip any '0' to a '1' or a '1' to a '0'.

Return the minimum number of flips to make S monotone increasing.

Example 1:

Input: "00110"
Output: 1
Explanation: We flip the last digit to get 00111.

Example 2:

Input: "010110"
Output: 2
Explanation: We flip to get 011111, or alternatively 000111.

Example 3:

Input: "00011000"
Output: 2
Explanation: We flip to get 00000000.

Note:

  1. 1 <= S.length <= 20000
  2. S only consists of '0' and '1' characters.

Solution: DP

l[i] := number of flips to make S[0] ~ S[i] become all 0s.

r[i] := number of flips to make S[i] ~ S[n – 1] become all 1s.

Try all possible break point, S[0] ~ S[i – 1] are all 0s and S[i] ~ S[n-1] are all 1s.

ans = min{l[i – 1] + r[i]}

Time complexity: O(n)

Space complexity: O(n)

C++

C++ v2

C++ v2 / O(1) Space

 

花花酱 LeetCode 920. Number of Music Playlists

Problem

Your music player contains N different songs and she wants to listen to L (not necessarily different) songs during your trip.  You create a playlist so that:

  • Every song is played at least once
  • A song can only be played again only if K other songs have been played

Return the number of possible playlists.  As the answer can be very large, return it modulo 10^9 + 7.

 

Example 1:

Input: N = 3, L = 3, K = 1
Output: 6
Explanation: There are 6 possible playlists. [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1].

Example 2:

Input: N = 2, L = 3, K = 0
Output: 6
Explanation: There are 6 possible playlists. [1, 1, 2], [1, 2, 1], [2, 1, 1], [2, 2, 1], [2, 1, 2], [1, 2, 2]

Example 3:

Input: N = 2, L = 3, K = 1
Output: 2
Explanation: There are 2 possible playlists. [1, 2, 1], [2, 1, 2]

Note:

  1. 0 <= K < N <= L <= 100

Solution: DP

dp[i][j] := # of playlists of length i using j different songs.

dp[i][j] = dp[i – 1][j – 1] * (N – (j – 1))  +  // Adding a new song. j – 1 used, choose any one from (N – (j – 1)) unused.
dp[i -1][j] * max(j – K, 0)         // Reuse an existing song.

Time complexity: O(LN)

Space complexity: O(LN) -> O(N)

C++/O(LN)

C++/O(N)

花花酱 LeetCode 901. Online Stock Span

Problem

Write a class StockSpanner which collects daily price quotes for some stock, and returns the span of that stock’s price for the current day.

The span of the stock’s price today is defined as the maximum number of consecutive days (starting from today and going backwards) for which the price of the stock was less than or equal to today’s price.

For example, if the price of a stock over the next 7 days were [100, 80, 60, 70, 60, 75, 85], then the stock spans would be [1, 1, 1, 2, 1, 4, 6].

Example 1:

Input: ["StockSpanner","next","next","next","next","next","next","next"], [[],[100],[80],[60],[70],[60],[75],[85]]
Output: [null,1,1,1,2,1,4,6]
Explanation: 
First, S = StockSpanner() is initialized.  Then:
S.next(100) is called and returns 1,
S.next(80) is called and returns 1,
S.next(60) is called and returns 1,
S.next(70) is called and returns 2,
S.next(60) is called and returns 1,
S.next(75) is called and returns 4,
S.next(85) is called and returns 6.

Note that (for example) S.next(75) returned 4, because the last 4 prices
(including today's price of 75) were less than or equal to today's price.

Note:

  1. Calls to StockSpanner.next(int price) will have 1 <= price <= 10^5.
  2. There will be at most 10000 calls to StockSpanner.next per test case.
  3. There will be at most 150000 calls to StockSpanner.next across all test cases.
  4. The total time limit for this problem has been reduced by 75% for C++, and 50% for all other languages.

 

Solution 1: Brute Force (TLE)

Time complexity: O(n) per next call

Space complexity: O(n)

Solution 2: DP

dp[i] := span of prices[i]

j = i – 1
while j >= 0 and prices[i] >= prices[j]: j -= dp[j]
dp[i] = i – j

C++

Solution 3: Monotonic Stack

Maintain a monotonic stack whose element are pairs of <price, span>, sorted by price from high to low.

When a new price comes in

  1. If it’s less than top price, add a new pair (price, 1) to the stack, return 1
  2. If it’s greater than top element, collapse the stack and accumulate the span until the top price is higher than the new price. return the total span

e.g. prices: 10, 6, 5, 4, 3, 7

after 3, the stack looks [(10,1), (6,1), (5,1), (4,1), (3, 1)],

when 7 arrives, [(10,1), (6,1), (5,1), (4,1), (3, 1), (7, 4 + 1)] = [(10, 1), (7, 5)]

Time complexity: O(1) amortized, each element will be pushed on to stack once, and pop at most once.

Space complexity: O(n), in the worst case, the prices is in descending order.

C++

Java

Python3

Related Problems