156th 周赛总结

这周的题目不难

Posted by Pacras on September 29, 2019

LeetCode 156th周赛

1.独一无二的出现次数

       题目描述:给定一个整数数组arr,如果数组中数字出现的次数各不相同则返回True,否则返回False

       思路:统计就可以了,利用set不包含重复元素的特性,查看长度是否相等即可。

代码:

from collections import defaultdict
class Solution:
    def uniqueOccurrences(self, arr: List[int]) -> bool:
        d = defaultdict(int)
        for num in arr:
            d[num] += 1
        if len(d.values()) == len(set(d.values())):
            return True
        else:
            return False

2.尽可能使字符串相等

       题目描述:给定长度相等的字符串st,使st的第i个字符相等的开销为两个字符ASCII码差值的绝对值。在最大开销预算maxCost的限定下,返回相等的子字符串的最大长度。

       思路:给定字符串后,很容易得到每个字符转化的开销数组,记为record。那么该问题就转化为,整数数组中和小于设定值的最小子数组长度。

代码:

class Solution:
    def equalSubstring(self, s: str, t: str, maxCost: int) -> int:
        record = [abs(ord(s[i]) - ord(t[i])) for i in range(len(s))]
        start, end, cost = 0, 0, 0
        l, res = 0, 0
        print(record)
        while end < len(t):
            if cost + record[end] <= maxCost:
                l += 1
                cost += record[end]
                end += 1
                res = max(res, l)
            else:
                l -= 1
                cost -= record[start]
                start += 1
            
        return res

3.删除字符串中所有的相邻重复项II

       题目描述:给定字符串s和整数k,删除sk个相邻且相等的字母,直到无法删除位置。需要注意的是,在一次删除之后,被删字符左右两侧可能又组成了需要被删的长度为k的相等字符,需要继续删除

       思路:利用栈来做:遍历字符串,如果栈空或者栈顶字符与当前字符不等,则添加到栈中;若相等,则将当前元素加到栈顶字符串中,若长度为k,则将栈顶元素弹出。

代码:

class Solution:
    def removeDuplicates(self, s: str, k: int) -> str:
        stack = []
        for c in s:
            if not stack or stack[-1][-1] != c:
                stack.append(c)
            else:
                stack[-1] += c
                if len(stack[-1]) == k:
                    stack.pop()
        return ''.join(stack)

4.穿越迷宫的最少移动次数

       题目描述:蛇的长度为2,迷宫大小为n*n,迷宫中0代表空单元格,1代表障碍物。求蛇从左上角(0,0)和(0,1)移动到右下角(n-1, n-2)和(n-1,n-1)的最小移动次数。

       蛇的移动方式:1、整体横向、纵向移动;2、如果蛇所在的四方格内均为障碍物,则蛇可以调整水平、竖直状态。

       思路:此类问题容易想到用动态规划来做。这道题的难点在于,蛇占了两个单元格,且有水平、竖直两种状态。蛇的移动可以根据蛇所在四方格内有无障碍物来划分:如果有障碍物,那么蛇只能沿着原方向前进;如果没有,那么蛇可以整体平移、调整方向。

代码:

class Solution:
    def minimumMoves(self, grid: List[List[int]]) -> int:
        n = len(grid)
        dp = [[[float('inf') for _ in range(2)] for _ in range(n)] for _ in range(n)]
        dp[0][0][0] = 0
        for i in range(n):
            for j in range(n):
                if not grid[i][j]:
                    # 有四方格,可以调整方向,或者做平移
                    
                    if i + 1 < n and j + 1 < n and not grid[i+1][j] and not grid[i][j+1] and not grid[i+1][j+1]:
                        # 水平方向可以由竖直方向逆时针旋转过来
                        
                        dp[i][j][0] = min(dp[i][j][0], dp[i][j][1]+1)
                        # 竖直方向可以由水平方向逆时针旋转过来
                        
                        dp[i][j][1] = min(dp[i][j][0] + 1, dp[i][j][1])
                        # 水平下移
                        
                        dp[i+1][j][0] = min(dp[i+1][j][0], dp[i][j][0] + 1)
                        # 竖直右移
                        
                        dp[i][j+1][1] = min(dp[i][j+1][1], dp[i][j][1] + 1)
                    # 没有四方格,只能往前移动
                    
                    if j + 2 < n and not grid[i][j+1] and not grid[i][j+2]:
                        dp[i][j+1][0] = min(dp[i][j+1][0], dp[i][j][0] + 1)
                    if i + 2 < n and not grid[i+1][j] and not grid[i+2][j]:
                        dp[i+1][j][1] = min(dp[i+1][j][1], dp[i][j][1] + 1)
                      
        return dp[n-1][n-2][0] if dp[n-1][n-2][0] != float('inf') else -1