leetcode practice - python3 (10)

198. House Robber

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that 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: [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.

Example 2:
Input: [2,7,9,3,1]
Output: 12
Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).
Total amount you can rob = 2 + 9 + 1 = 12.

思路:DP
dp[i] = max(dp[i-1], dp[i-2] + nums[i])

class Solution:
    def rob(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        length = len(nums)
        if length == 0:
            return 0
        if length == 1:
            return nums[0]
        if length == 2:
            return nums[0] if nums[0] > nums[1] else nums[1]

        dp = [0] * len(nums)
        dp[0] = nums[0]
        dp[1] = nums[1] if nums[1] > nums[0] else nums[0]
        for i in range(2, len(nums)):
            dp[i] = dp[i-1]
            if dp[i-2] + nums[i] > dp[i]:
                dp[i] = dp[i-2] + nums[i]

        return dp[length - 1]

Beat 98.56% python3 2018-05-28

减少空间使用:

class Solution:
    def rob(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        length = len(nums)
        if length == 0:
            return 0
        if length == 1:
            return nums[0]

        dp = [nums[0], max(nums[0], nums[1]), 0]
        sum = 0
        for i in range(2, len(nums)):
            sum = dp[0] + nums[i]
            dp[2] = sum if sum > dp[1] else dp[1]
            dp[0] = dp[1]
            dp[1] = dp[2]

        return dp[1]

Beat 98.56% python3 2018-05-28

581. Shortest Unsorted Continuous Subarray

Given an integer array, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order, too.

You need to find the shortest such subarray and output its length.

Example 1:
Input: [2, 6, 4, 8, 10, 9, 15]
Output: 5
Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order.
Note:
Then length of the input array is in range [1, 10,000].
The input array may contain duplicates, so ascending order here means <=.

思路:从左往右,找升序序列,找到l, 从l找一个最小值
从右往左,找降序序列,找到r,从r找一个最大值
首先l, r之间肯定是需要重排序的,而0到l,若有比min小的,则左移l,若r, lenght-1有比max大的则右移r

class Solution:
    def findUnsortedSubarray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        flag = False
        min_num, max_num = sys.maxsize, -sys.maxsize
        for i in range(1, len(nums)):
            if nums[i] < nums[i-1]:
                flag = True
            if flag:
                min_num = min(min_num, nums[i])

        flag = False
        for i in range(len(nums) - 2, -1, -1):
            if nums[i] > nums[i+1]:
                flag = True
            if flag:
                max_num = max(max_num, nums[i])

        l, r = 0, len(nums) - 1
        while l < len(nums) and min_num >= nums[l]:
            l += 1
        while r >= 0 and max_num <= nums[r]:
            r -= 1

        return r - l + 1 if r > l else 0

Beat 29.29% python3 2018-05-28

优化:[0, l] 为一个升序序列, [r, length-1]为一个升序序列
找[l, r]中的min,max,[0, l]中找到大于min的位置,[r, length-1]中找到小于max的位置

class Solution:
    def findUnsortedSubarray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        length = len(nums)

        l = 0
        while l < length-1 and nums[l] <= nums[l+1]:
            l += 1
        if l == length-1:
            return 0

        r = length-1
        while r > 0 and nums[r] >= nums[r-1]:
            r -= 1
        if r == 0:
            return 0

        min_num, max_num = sys.maxsize, -sys.maxsize
        for i in range(l, r+1):
            min_num = min(min_num, nums[i])
            max_num = max(max_num, nums[i])

        i, j = 0, length-1
        while i < l and nums[i] <= min_num:
            i += 1
        while j > r and nums[j] >= max_num:
            j -= 1

        return j - i + 1

Beat 52.14% python3 2018-05-28

优化:不使用内置函数min, max

class Solution:
    def findUnsortedSubarray(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        length = len(nums)

        l = 0
        while l < length-1 and nums[l] <= nums[l+1]:
            l += 1
        if l == length-1:
            return 0

        r = length-1
        while r > 0 and nums[r] >= nums[r-1]:
            r -= 1

        min_num, max_num = sys.maxsize, -sys.maxsize
        for i in range(l, r+1):
            if nums[i] < min_num:
                min_num = nums[i]
            if nums[i] > max_num:
                max_num = nums[i]

        i, j = 0, length-1
        while i < l and nums[i] <= min_num:
            i += 1
        while j > r and nums[j] >= max_num:
            j -= 1

        return j - i + 1

Beat 97.14% python3 2018-05-28

437. Path Sum III

You are given a binary tree in which each node contains an integer value.

Find the number of paths that sum to a given value.

The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).

The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.

Example:

root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8

10
/ \
5 -3
/ \ \
3 2 11
/ \ \
3 -2 1

Return 3. The paths that sum to 8 are:

  1. 5 -> 3
  2. 5 -> 2 -> 1
  3. -3 -> 11

思路1:递归

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def pathSum(self, root, sum):
        """
        :type root: TreeNode
        :type sum: int
        :rtype: int
        """
        if root is None:
            return 0

        return self.sum(root, sum) + self.pathSum(root.left, sum) + self.pathSum(root.right, sum)

    def sum(self, root, s):
        if root is None:
            return 0

        ans = 1 if root.val == s else 0
        return ans + self.sum(root.left, s-root.val) + self.sum(root.right, s-root.val)

Beat 34.33% python3 2018-05-29

优化:记住路径上的和

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

from collections import defaultdict
class Solution:
    def pathSum(self, root, sum):
        """
        :type root: TreeNode
        :type sum: int
        :rtype: int
        """
        if root is None:
            return 0

        dict = defaultdict(int)
        dict[0] = 1
        return self.solve(root, sum, 0, dict)


    def solve(self, root, target, cur, dict):
        cur += root.val
        ans = dict[cur - target]

        dict[cur] += 1
        if root.left:
            ans += self.solve(root.left, target, cur, dict)
        if root.right:
            ans += self.solve(root.right, target, cur, dict)
        dict[cur] -= 1

        return ans

Beat 99.00% python3 2018-05-29

287. Find the Duplicate Number

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.

Example 1:
Input: [1,3,4,2,2]
Output: 2

Example 2:
Input: [3,1,3,4,2]
Output: 3
Note:

You must not modify the array (assume the array is read only).
You must use only constant, O(1) extra space.
Your runtime complexity should be less than O(n2).
There is only one duplicate number in the array, but it could be repeated more than once.

思路:类似链表找环的开始位置

class Solution:
    def findDuplicate(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        slow = nums[0]
        fast, t = slow, slow
        while True:
            slow = nums[slow]
            fast = nums[nums[fast]]
            if fast == slow:
                break

        while t != slow:
            t = nums[t]
            slow = nums[slow]

        return t

Beat 99.73% python3 2018-05-30

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
Note:
You may assume that you have an infinite number of each kind of coin.

思路1:DP,背包问题

class Solution:
    def coinChange(self, coins, amount):
        """
        :type coins: List[int]
        :type amount: int
        :rtype: int
        """
        dp = [sys.maxsize] * (amount + 1)
        dp[0] = 0

        for i in range(amount+1):
            for c in coins:
                if i >= c and dp[i-c] >= 0 and dp[i-c] + 1 < dp[i]:
                    dp[i] = 1 + dp[i-c]

        return -1 if dp[amount] == sys.maxsize else dp[amount]

Beat 71.06% python3 2018-05-31

思路2:DFS,剪枝(硬币数已大于最小值,用当前剩下的最大面值*(当前最小硬币数 - 当前硬币数)不足以组合出目标值

class Solution:
    def coinChange(self, coins, amount):
        """
        :type coins: List[int]
        :type amount: int
        :rtype: int
        """
        def dfs(current, index, target):
            if target == 0:
                if current < self.ans:
                    self.ans = current

            if current >= self.ans:
                return

            for i in range(index, len(coins)):
                if coins[i] <= target and coins[i]*(self.ans - current) >= target:
                    dfs(current+1, i, target-coins[i])

        coins = sorted(coins, reverse=True)
        self.ans = sys.maxsize
        dfs(0, 0, amount)
        return -1 if self.ans == sys.maxsize else self.ans

Beat 98.38% python3 2018-05-30

你可能感兴趣的:(算法,python3,leetcode,leetcode,python3,algorithm)