題目以下:less
We are given an array
A
ofN
lowercase letter strings, all of the same length.spaNow, we may choose any set of deletion indices, and for each string, we delete all the characters in those indices.code
For example, if we have an array
A = ["babca","bbazb"]
and deletion indices{0, 1, 4}
, then the final array after deletions is["bc","az"]
.blogSuppose we chose a set of deletion indices
D
such that after deletions, the final array has every element (row) in lexicographic order.elementFor clarity,
A[0]
is in lexicographic order (ie.A[0][0] <= A[0][1] <= ... <= A[0][A[0].length - 1]
),A[1]
is in lexicographic order (ie.A[1][0] <= A[1][1] <= ... <= A[1][A[1].length - 1]
), and so on.inputReturn the minimum possible value of
D.length
.stringExample 1:it
Input: ["babca","bbazb"] Output: 3 Explanation: After deleting columns 0, 1, and 4, the final array is A = ["bc", "az"]. Both these rows are individually in lexicographic order (ie. A[0][0] <= A[0][1] and A[1][0] <= A[1][1]). Note that A[0] > A[1] - the array A isn't necessarily in lexicographic order.
Example 2:io
Input: ["edcba"] Output: 4 Explanation: If we delete less than 4 columns, the only row won't be lexicographically sorted.
Example 3:class
Input: ["ghi","def","abc"] Output: 0 Explanation: All rows are already lexicographically sorted.
Note:
1 <= A.length <= 100
1 <= A[i].length <= 100
解題思路:本題能夠採用動態規劃的方法。記dp[i][0] = v表示不刪除第i個元素時,使得0~i子區間有序須要刪除掉v個字符,dp[i][1] = v表示刪除第i個元素時,使得0~i子區間有序須要刪除掉v個字符。先看第二種狀況,由於對第i個元素刪除操做,因此其值徹底和dp[i-1]有關,有dp[i][1] = min(dp[i-1][0],dp[i-1][1]) + 1,取第i個元素刪除或者不刪除時候的較小值;而若是第i個元素保留,那麼咱們只須要找出離i最近的保留的元素j,使得Input 中每個元素 item 都須要知足 item[i] > item[j],這樣的j可能不存在或者有多個,找出知足 dp[i][0] = min(dp[i][0],dp[j][0] + (i-j-1)) 最小的便可,若是沒有這樣的j存在,令dp[i][0] = i。最後的結果爲 dp[-1][0]和dp[-1][1]中的較小值。
代碼以下:
class Solution(object): def minDeletionSize(self, A): """ :type A: List[str] :rtype: int """ dp = [[float('inf')] * 2 for _ in A[0]] dp[0][0] = 0 # 0 : keep; 1:delete dp[0][1] = 1 for i in range(1,len(A[0])): dp[i][1] = min(dp[i-1][0],dp[i-1][1]) + 1 dp[i][0] = i for j in range(i): flag = True for k in range(len(A)): if A[k][i] < A[k][j]: flag = False break if flag: dp[i][0] = min(dp[i][0],dp[j][0] + (i-j-1)) return min(dp[-1])