Leetcode刷题笔记2-dp

213. House Robber II

dp, 首尾是环,转换成2部分

  1. Rob houses 0 to n - 2;
  2. Rob houses 1 to n - 1.

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

Example 1:

Input: [2,3,2]
Output: 3
Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2),
             because they are adjacent houses.

Example 2:

Input: [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
             Total amount you can rob = 1 + 3 = 4.
class Solution(object):
    def rob(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) == 1:
            return nums[0]
    
        def robHouse(nums, low, high):
            i1 = i2 = 0
            cur = 0
            for i in xrange(low, high):
                cur = max(i1, i2+nums[i])
                i2 = i1
                i1 = cur
            return cur
        
        return max(robHouse(nums, 0, len(nums)-1), robHouse(nums, 1, len(nums)))

368. Largest Divisible Subset 

LIS算法的变形,原理一样

Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of elements in this subset satisfies: Si % Sj = 0 or Sj % Si = 0.

If there are multiple solutions, return any subset is fine.

Example 1:

nums: [1,2,3]

Result: [1,2] (of course, [1,3] will also be ok)

Example 2:

nums: [1,2,4,8]

Result: [1,2,4,8]
class Solution(object):
    def largestDivisibleSubset(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        if not nums:
            return []
        
        nums = sorted(nums)
        dp = [[nums[0]] for i in nums]
        res = [nums[0]]
        for i in xrange(1, len(nums)):
            dp[i] = [nums[i]]
            for j in xrange(0, i):
                if nums[i] % nums[j] == 0:
                    dp[i] = dp[j] + [nums[i]] if len(dp[j]) >= len(dp[i]) else dp[i]
            res = dp[i] if len(res) < len(dp[i]) else res
        return res

263. Ugly Number

给ugly Number 2做铺垫

Write a program to check whether a given number is an ugly number.

Ugly numbers are positive numbers whose prime factors only include 2, 3, 5.

Example 1:

Input: 6
Output: true
Explanation: 6 = 2 × 3

Example 2:

Input: 8
Output: true
Explanation: 8 = 2 × 2 × 2

Example 3:

Input: 14
Output: false 
Explanation: 14 is not ugly since it includes another prime factor 7.
class Solution(object):
    def isUgly(self, num):
        """
        :type num: int
        :rtype: bool
        """
        
        rest = num
        if rest == 0:
            return False
        while rest != 1:
            if rest % 2 == 0:
                rest /= 2
            elif rest % 3 == 0:
                rest /= 3
            elif rest % 5 == 0:
                rest /= 5
            else:
                return False
            
        return True

别人的写法:汗颜,学习了。

for p in 2, 3, 5:
    while num % p == 0 < num:
        num /= p
return num == 1

264. Ugly Number II

Write a program to find the n-th ugly number.

Ugly numbers are positive numbers whose prime factors only include 2, 3, 5

Example:

Input: n = 10
Output: 12
Explanation: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.
class Solution(object):
    def nthUglyNumber(self, n):
        """
        :type n: int
        :rtype: int
        """
        dp = [1]*(n+1)
        n2 = n3 = n5 = 1

        for i in xrange(2, n+1):
            dp[i] = min(dp[n2]*2, dp[n3]*3, dp[n5]*5)
            
            if dp[n2]*2 == dp[i]:
                n2 += 1
            if dp[n3]*3 == dp[i]:
                n3 += 1
            if dp[n5]*5 == dp[i]:
                n5 += 1
        return dp[n]
        

Explanation:

The key is to realize each number can be and have to be generated by a former number multiplied by 2, 3 or 5
e.g.
1 2 3 4 5 6 8 9 10 12 15..
what is next?
it must be x * 2 or y * 3 or z * 5, where x, y, z is an existing number.

How do we determine x, y, z then?
apparently, you can just traverse the sequence generated by far from 1 … 15, until you find such x, y, z that x * 2, y * 3, z * 5 is just bigger than 15. In this case x=8, y=6, z=4. Then you compare x * 2, y * 3, z * 5 so you know next number will be x * 2 = 8 * 2 = 16.
k, now you have 1,2,3,4,….,15, 16,

Then what is next?
You wanna do the same process again to find the new x, y, z, but you realize, wait, do I have to
traverse the sequence generated by far again?

NO! since you know last time, x=8, y=6, z=4 and x=8 was used to generate 16, so this time, you can immediately know the new_x = 9 (the next number after 8 is 9 in the generated sequence), y=6, z=4.
Then you need to compare new_x * 2, y * 3, z * 5. You know next number is 9 * 2 = 18;

And you also know, the next x will be 10 since new_x = 9 was used this time.
But what is next y? apparently, if y=6, 6*3 = 18, which is already generated in this round. So you also need to update next y from 6 to 8.

Based on the idea above, you can actually generated x,y,z from very beginning, and update x, y, z accordingly. It ends up with a O(n) solution.

467. Unique Substrings in Wraparound String

Consider the string s to be the infinite wraparound string of “abcdefghijklmnopqrstuvwxyz”, so s will look like this: “…zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd….”.

Now we have another string p. Your job is to find out how many unique non-empty substrings of p are present in s. In particular, your input is the string p and you need to output the number of different non-empty substrings of p in the string s.

Note: p consists of only lowercase English letters and the size of p might be over 10000.

Example 1:

Input: "a"
Output: 1

Explanation: Only the substring "a" of string "a" is in the string s.

Example 2:

Input: "cac"
Output: 2
Explanation: There are two substrings "a", "c" of string "cac" in the string s.

Example 3:

Input: "zab"
Output: 6
Explanation: There are six substrings "z", "a", "b", "za", "ab", "zab" of string "zab" in the string s.

思路:

  1. The max number of unique substring ends with a letter equals to the length of max contiguous substring ends with that letter. Example "abcd", the max number of unique substring ends with 'd' is 4, apparently they are "abcd", "bcd", "cd" and "d".
  2. If there are overlapping, we only need to consider the longest one because it covers all the possible substrings. Example: "abcdbcd", the max number of unique substring ends with 'd' is 4 and all substrings formed by the 2nd "bcd" part are covered in the 4 substrings already.
  3. No matter how long is a contiguous substring in p, it is in s since s has infinite length.
  4. Now we know the max number of unique substrings in p ends with 'a', 'b', ..., 'z' and those substrings are all in s. Summary is the answer, according to the question.
class Solution(object):
    def findSubstringInWraproundString(self, p):
        """
        :type p: str
        :rtype: int
        """
        dp = [0] * 26
        longest = 1
        
        for i in xrange(0, len(p)):
            if i == 0:
                longest = 1
            elif ord(p[i]) - ord(p[i-1]) in (1, -25):
                longest += 1 
            else:
                longest = 1
            index = ord(p[i]) - ord('a')
            dp[index] = max(dp[index], longest)
        
        return sum(dp)

139. Word Break

《Leetcode刷题笔记2-dp》

思路:

《Leetcode刷题笔记2-dp》

class Solution(object):
    def wordBreak(self, s, wordDict):
        """
        :type s: str
        :type wordDict: List[str]
        :rtype: bool
        """
        
        dp = [False] * len(s)
        
        for i in xrange(0, len(s)):
            for w in wordDict:
                if i-len(w)+1 >= 0:
                    if w == s[i-len(w)+1: i+1] and (dp[i-len(w)] or i-len(w) == -1):
                        dp[i] = True
        return dp[-1]

673. Number of Longest Increasing Subsequence

Given an unsorted array of integers, find the number of longest increasing subsequence.

Example 1:

Input: [1,3,5,4,7]
Output: 2
Explanation: The two longest increasing subsequence are [1, 3, 4, 7] and [1, 3, 5, 7].

Example 2:

Input: [2,2,2,2,2]
Output: 5
Explanation: The length of longest continuous increasing subsequence is 1, and there are 5 subsequences' length is 1, so output 5.

思路:

The idea is to use two arrays len[n] and cnt[n] to record the maximum length of Increasing Subsequence and the coresponding number of these sequence which ends with nums[i], respectively. That is:

len[i]: the length of the Longest Increasing Subsequence which ends with nums[i].
cnt[i]: the number of the Longest Increasing Subsequence which ends with nums[i].

Then, the result is the sum of each cnt[i] while its corresponding len[i] is the maximum length.

class Solution(object):
    def findNumberOfLIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:
            return 0
        
        
        count, dp = [0 for i in nums], [1 for i in nums]
        
        for i in xrange(1, len(nums)):
            for j in xrange(0, i):
                if nums[j] < nums[i]:
                    dp[i] = max(dp[i], dp[j]+1)
                    
            for j in xrange(0, i):
                if nums[j] < nums[i] and dp[i]-1 == dp[j]:
                    count[i] += count[j] if count[j] else 1
        
        res = 0
        for i in xrange(len(nums)):
            if dp[i] == max(dp):
                res += count[i]
                
        return res if res else len(nums)

221. Maximal Square

DP

Given a 2D binary matrix filled with 0’s and 1’s, find the largest square containing only 1’s and return its area.

Example:

Input: 

1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0

Output: 4

思路:

This problem can be solved by dynamic programming. They key to DP is the state equation. In this problem, we define the state as the maximal size of the square that can be achieved at point (i, j), denoted as dp[i][j]. Remember that we use size instead of square as the state (square = size * size).

Now let’s try to come up with the formula for dp[i][j].

First, it is obvious that for the topmost row (i = 0) and the leftmost column (j = 0), dp[i][j] = matrix[i][j]. For example, if he topmost row of matrix is [1, 0, 0, 1], we immediately know that the first and last point can be a square of size 1 while the two middle points cannot make any square, giving a size of 0. Thus, dp = [1, 0, 0, 1], which is the same as matrix. The case is similar for the leftmost column. Till now, the boundary conditions of this DP problem are solved.

Let’s move to the more general case for dp[i][j] in which i > 0 and j > 0. First of all, let’s see a simple sub-case in which matrix[i][j] = 0. It is obvious that dp[i][j] = 0 since if matrix[i][j] = 0, no square will contain matrix[i][j]. According to our definition of dp[i][j]dp[i][j] is also 0.

Now we are almost done. The remaining sub-case is matrix[i][j] = 1. Suppose matrix = [[0, 1], [1, 1]], it is obvious that dp[0][0] = 0, dp[0][1] = dp[1][0] = 1, what about dp[1][1]? Well, to give a square of size larger than 1 in dp[1][1], all of its three neighbors (left, upper, upper-left) should be non-zero. In this case, the upper-left neighbor dp[0][0] = 0, so dp[1][1] can only be 1, which means that the square only contains matrix[1][1]. To summarize, dp[i][j] = min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1 in this case.

The state equations are finally as follows.

  1. dp[0][j] = matrix[0][j] (topmost row);
  2. dp[i][0] = matrix[i][0] (leftmost column);
  3. For i > 0 and j > 0: if matrix[i][j] = 0dp[i][j] = 0; if matrix[i][j] = 1dp[i][j] = min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1.
class Solution(object):
    def maximalSquare(self, matrix):
        """
        :type matrix: List[List[str]]
        :rtype: int
        """
        if not matrix:
            return 0
        
        row = len(matrix)
        col = len(matrix[0])
        
        size = [[0] * col for i in matrix]
        
        res = 0
        for i in xrange(row):
            for j in xrange(col):
                if col == 0:
                    size[i][j] = int(matrix[i][j])
                else:
                    size[i][j] = min(size[i-1][j], size[i][j-1], size[i-1][j-1]) + 1 if int(matrix[i][j]) else 0
                     
                res = max(res, size[i][j])
        
        return res*res

576. Out of Boundary Paths

There is an m by n grid with a ball. Given the start coordinate (i,j) of the ball, you can move the ball to adjacent cell or cross the grid boundary in four directions (up, down, left, right). However, you can at most move N times. Find out the number of paths to move the ball out of grid boundary. The answer may be very large, return it after mod 109 + 7.

Example 1:

Input:m = 2, n = 2, N = 2, i = 0, j = 0
Output: 6
Explanation:

 

Example 2:

Input:m = 1, n = 3, N = 3, i = 0, j = 1
Output: 12
Explanation:

Note:

  1. Once you move the ball out of boundary, you cannot move it back.
  2. The length and height of the grid is in range [1,50].
  3. N is in range [0,50].
  1. 这道题乍一看很像一个标准的bfs,因为限定最多只能移动N次,我们只要bfs依次遍历发现出界就+1,当bfs的深度大于N的时候break。当然理论上是没有任何问题的,确实能得出正确答案,但是这里N的取值范围达到了50,我们对任意一个点bfs有四个方向(可以走回头路),那么复杂度达到了4^N,显然会超时。当然我会在文章后面给出bfs的做法,毕竟这是可以处理N比较小的情况的解法,让大家更熟悉bfs的套路。
  2. 我不知道你们有没有这种感觉,一般看到这个mod 1e9+7,这道题8成就是dp了,而且就是那种每个dp值你都得mod一下再去进行运算的那种。我觉得这算一个小技巧吧,看到mod 1e9+7就要想到dp。
  3. 显然,这里dp很好定义,我们定义dp[(i,j,N)]表示从i,j出发,最多走N步情况下满足题意的路径数量,那么我们所求也就是dp[(i,j,N)]。根据我们上面说的bfs的思路,递推式可得:
    dp[(i,j,N)] = dp[(i+1,j,N-1)] + dp[(i-1,j,N-1)] + dp[(i,j+1,N-1)] + dp[(i,j-1,N-1)]
class Solution(object):
    def findPaths(self, m, n, N, i, j):
        """
        :type m: int
        :type n: int
        :type N: int
        :type i: int
        :type j: int
        :rtype: int
        """
        mod = 10**9 + 7
        cache = collections.defaultdict(int)
        
        def helper(N, i, j, cache):
            if (i, j, N) in cache:
                return cache[(i, j, N)]
            
            if 0<=i<m and 0<=j<n:
                if N == 0:
                    cache[(i, j, N)] = 0
                    return 0
                
                for x, y in ((i-1, j), (i+1, j), (i, j-1), (i, j+1)):
                    cache[(i, j, N)] += helper(N-1, x, y, cache)
                
                return cache[(i, j, N)] % mod
            else:
                cache[(i, j, N)] = 1
                return 1
            
        return helper(N, i, j, cache)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def findPaths(m,n,N,i,j):
    mod = 10**9 + 7
    Q = collections.deque([(i,j,0)])
    res = 0
    while Q:
        x,y,step = Q.popleft()
        if step > N: break
        if 0<=x<m and 0<=y<n:
            Q.append((x+1,y,step+1))
            Q.append((x-1,y,step+1))
            Q.append((x,y+1,step+1))
            Q.append((x,y-1,step+1))
        else:
            res += 1
    return res % mod

 787. Cheapest Flights Within K Stops

Dijkstra’s algorithm 每次更新剩余点到起始点的价格。

There are n cities connected by m flights. Each fight starts from city and arrives at v with a price w.

Now given all the cities and fights, together with starting city src and the destination dst, your task is to find the cheapest price from src to dst with up to k stops. If there is no such route, output -1.

Example 1:
Input: 
n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]]
src = 0, dst = 2, k = 1
Output: 200
Explanation: 
The graph looks like this:


The cheapest price from city 0 to city 2 with at most 1 stop costs 200, as marked red in the picture.
Example 2:
Input: 
n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]]
src = 0, dst = 2, k = 0
Output: 500
Explanation: 
The graph looks like this:


The cheapest price from city 0 to city 2 with at most 0 stop costs 500, as marked blue in the picture.
class Solution(object):
    def findCheapestPrice(self, n, flights, src, dst, K):
        """
        :type n: int
        :type flights: List[List[int]]
        :type src: int
        :type dst: int
        :type K: int
        :rtype: int
        """
        prices = collections.defaultdict(dict)
        
        for a, b, p in flights:
            prices[a][b] = p
        
        heap = [(0, src, K+1)]
        while heap:
            price, curPlace, steps = heapq.heappop(heap)
            if curPlace == dst:
                return price
            
            if steps > 0:
                for arr in prices[curPlace]:
                    heapq.heappush(heap, (price+prices[curPlace][arr], arr, steps-1))
        return -1
    

304. Range Sum Query 2D – Immutable 

Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner (row1, col1) and lower right corner (row2, col2).

《Leetcode刷题笔记2-dp》
The above rectangle (with the red border) is defined by (row1, col1) = (2, 1) and (row2, col2) = (4, 3), which contains sum = 8.

Example:

Given matrix = [
  [3, 0, 1, 4, 2],
  [5, 6, 3, 2, 1],
  [1, 2, 0, 1, 5],
  [4, 1, 0, 1, 7],
  [1, 0, 3, 0, 5]
]

sumRegion(2, 1, 4, 3) -> 8
sumRegion(1, 1, 2, 2) -> 11
sumRegion(1, 2, 2, 4) -> 12
class NumMatrix(object):

    def __init__(self, matrix):
        """
        :type matrix: List[List[int]]
        """
        dpSum = [[0]*len(matrix[0]) for i in matrix]
        
        for i in xrange(len(matrix)):
            for j in xrange(len(matrix[0])):
                if j-1>=0:
                    dpSum[i][j] += dpSum[i][j-1]
                for row in xrange(0, i+1):
                     dpSum[i][j] += matrix[row][j]
        self.dpSum = dpSum

    def sumRegion(self, row1, col1, row2, col2):
        """
        :type row1: int
        :type col1: int
        :type row2: int
        :type col2: int
        :rtype: int
        """
        
        res = self.dpSum[row2][col2] 
        if col1 - 1 >= 0:
            res -= self.dpSum[row2][col1-1]
        if row1 -1 >= 0:
            res -= self.dpSum[row1-1][col2]
        if col1 - 1 >= 0 and row1 -1 >= 0:
            res += self.dpSum[row1-1][col1-1]
        return res

# Your NumMatrix object will be instantiated and called as such:
# obj = NumMatrix(matrix)
# param_1 = obj.sumRegion(row1,col1,row2,col2)

322. Coin Change

You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.

Example 1:

Input: coins = [1, 2, 5], amount = 11
Output: 3 
Explanation: 11 = 5 + 5 + 1

Example 2:

Input: coins = [2], amount = 3
Output: -1
class Solution(object):
    def coinChange(self, coins, amount):
        """
        :type coins: List[int]
        :type amount: int
        :rtype: int
        """
        
        dp = collections.defaultdict(int)
        coins = sorted(coins)
        for money in xrange(1, amount+1):
            minCoins = 5000
            for coin in coins:
                if money-coin>=0 and dp[money-coin] != -1:
                    minCoins = min(dp[money-coin], minCoins)
            if minCoins == 5000:
                dp[money] = -1
            else:
                dp[money] = minCoins + 1
        return dp[amount]

464. Can I Win

游戏的可以整理一篇,都是暴力破解(递归)加记忆。DP用于记录计算过的路径避免重复计算。

In the “100 game,” two players take turns adding, to a running total, any integer from 1..10. The player who first causes the running total to reach or exceed 100 wins.

What if we change the game so that players cannot re-use integers?

For example, two players might take turns drawing from a common pool of numbers of 1..15 without replacement until they reach a total >= 100.

Given an integer maxChoosableInteger and another integer desiredTotal, determine if the first player to move can force a win, assuming both players play optimally.

You can always assume that maxChoosableInteger will not be larger than 20 and desiredTotal will not be larger than 300.

Example

Input:
maxChoosableInteger = 10
desiredTotal = 11

Output:
false

Explanation:
No matter which integer the first player choose, the first player will lose.
The first player can choose an integer from 1 up to 10.
If the first player choose 1, the second player can only choose integers from 2 up to 10.
The second player will win by choosing 10 and get a total = 11, which is >= desiredTotal.
Same with other integers chosen by the first player, the second player will always win.
class Solution(object):
    def canIWin(self, maxChoosableInteger, desiredTotal):
        """
        :type maxChoosableInteger: int
        :type desiredTotal: int
        :rtype: bool
        """
        
        allowed = [x for x in xrange(1, maxChoosableInteger+1)]
        if sum(allowed) < desiredTotal:
            return False
        return self.helper(allowed, desiredTotal, 0, {})
    
    
    def helper(self, allowed, target, so_far, cache):
        if len(allowed) == 0:
            return False
        state = tuple(allowed)
        if state in cache:
            return cache[state]
        else:
            cache[state] = False
            if max(allowed) + so_far >= target:
                cache[state] = True
            else:
                for x in allowed:
                    new_allowed = [y for y in allowed if x!= y]  # opponent 
                    #If with any choice the opponent fails for sure, then also I can win for sure from this state.
                    if self.helper(new_allowed, target, so_far+x, cache) == False: 
                        cache[state] = True
                        break
        return cache[state]
                        

523. Continuous Subarray Sum 

Given a list of non-negative numbers and a target integer k, write a function to check if the array has a continuous subarray of size at least 2 that sums up to the multiple of k, that is, sums up to n*k where n is also an integer.

Example 1:

Input: [23, 2, 4, 6, 7],  k=6
Output: True
Explanation: Because [2, 4] is a continuous subarray of size 2 and sums up to 6.

Example 2:

Input: [23, 2, 6, 4, 7],  k=6
Output: True
Explanation: Because [23, 2, 6, 4, 7] is an continuous subarray of size 5 and sums up to 42.

Note:

  1. The length of the array won’t exceed 10,000.
  2. You may assume the sum of all the numbers is in the range of a signed 32-bit integer.

思路:

暴力破解就不说了,

在讨论里有个大神给出了时间复杂度是O(nn)的解法,他的思路非常巧妙,用了数学上的知识,下面给出他的解法的原理: 
假设: 

a[i]+a[i+1]+…+a[j]=n1k+q;a[i]+a[i+1]+…+a[j]=n1k+q;

如果存在一个n 

n>j且a[i]+a[i+1]+…+a[j]+…+a[n]=n2k+q;n>j且a[i]+a[i+1]+…+a[j]+…+a[n]=n2k+q;

那么 

a[j+1]+…+a[n]=(n2−n1)ka[j+1]+…+a[n]=(n2−n1)k

因此利用这一结果,可以从序列第一个元素开始遍历,不断累加上当前的元素,并求出当前和除以k后的余数,用一个映射记录该余数出现时的下标,如果同一个余数出现了两次,并且两次出现的下标之差大于1,那么就表示在这两个座标之间的元素之和是k的倍数,因此就可以返回true,否则最后返回false。 
需要注意的两个地方: 
1. k可能取0,所以只有当k不为0时才对当前的和求余,同时针对于nums = [0, 0], k = 0的情况,需要添加一个初始映射(0, -1)来确保结果的正确。 
2. 下标之差至少为2才算是正确的情况,因为题目要求子序列长度至少为2,以上面的例子就是n至少等于j+2。 
具体实现见下面参考代码。

class Solution(object):
    def checkSubarraySum(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: bool
        """
        if len(nums) < 2:
            return False
        
        if k == 0:
            for i in range(0, len(nums) - 1):
                if nums[i] == 0 and nums[i+1] == 0:
                    return True
            return False
        
        k = abs(k)
        if len(nums) >= 2*k:
            return True
        
        Sum = [0]
        for x in nums:
            Sum.append((Sum[-1]+x)%k)
            
        Dict = {}
        for i in xrange(len(Sum)):
            if Dict.has_key(Sum[i]):
                if i - Dict[Sum[i]] >= 2:
                    return True
            else:
                Dict[Sum[i]] = i
            
        return False
        

91. Decode Ways 

A message containing letters from A-Z is being encoded to numbers using the following mapping:

'A' -> 1
'B' -> 2
...
'Z' -> 26

Given a non-empty string containing only digits, determine the total number of ways to decode it.

Example 1:

Input: "12"
Output: 2
Explanation: It could be decoded as "AB" (1 2) or "L" (12).

Example 2:

Input: "226"
Output: 3
Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).

i指的是字符串长度。

class Solution(object):
    def numDecodings(self, s):
        """
        :type s: str
        :rtype: int
        """
        if s[0] == '0':
            return 0
        
        dp = [0 for i in xrange(len(s)+1)]
        dp[0] = 1
        dp[1] = 0 if s[0] == '0' else 1
        for i in xrange(2, len(s)+1):
            one = int(s[i-1])
            two = int(s[i-2:i])
            
            if 1 <= one:
                dp[i] = dp[i-1]
                
            if 10 <= two <= 26:
                dp[i] += dp[i-2]
            
        return dp[-1]
点赞