leetcode刷题记录481-490 python版

前言

继续leetcode刷题生涯
这里记录的都是笔者觉得有点意思的做法
参考了好几位大佬的题解,尤其是powcai大佬和labuladong大佬,感谢各位大佬

481. 神奇字符串

class Solution:
    def magicalString(self, n: int) -> int:
        if n==0:return 0
        string = '122'
        i = 2
        char = 2
        ones=1
        while len(string) < n:
            char = 2 - char // 2
            if char==1:
                ones+=int(string[i])
            string += int(string[i])*str(char)
            i+=1
        return ones-1 if char==1 and len(string)>n else ones

482. 密钥格式化

class Solution:
    def licenseKeyFormatting(self, S: str, K: int) -> str:
        S = ''.join(S.upper().split('-'))
        m, n = len(S) % K, len(S) // K
        sl = '-'.join([S[m+i*K:m+(i+1)*K] for i in range(n)])
        if m == 0:
            return sl
        if n == 0:
            return S[:m]
        return S[:m] + '-' + sl

483. 最小好进制

import math
class Solution:
    def smallestGoodBase(self, n: str) -> str:
        if n == 1: return '1'
        n = int(n)
        max_k = int(math.log2(n) + 1)
        for k in range(max_k, 1, -1):
            x = int(n ** (1/(k-1)))
            while x >= 2:
                if x ** k - 1 == (x - 1) * n and x != 1:
                    return str(x)
                if (x**k -1) / (x-1) < n:
                    break
                x -= 1
        # k大于等于2时候x找不到,x只可能等于n-1了
        return str(n-1)

485. 最大连续1的个数

class Solution:
    def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
        res, cnt = 0, 0
        for num in nums + [0]:
            if num == 0:
                res = max(cnt, res)
                cnt = 0
            else:
                cnt += 1
        return res

486. 预测赢家

# dp
class Solution:
    def PredictTheWinner(self, nums) -> bool:
        n = len(nums)
        if n<= 2:
            return True
        dp = [[0] * n for _ in range(n)]
        for i in range(n):
            dp[i][i] = nums[i]  #对角线可以直接获取
        for k in range(1, n):  #k表示j-i的距离
            for i in range(0, n - k):
                dp[i][i + k] = max(sum(nums[i + 1:i + k + 1]) - dp[i + 1][i + k] + nums[i],
                                   sum(nums[i:i + k]) - dp[i][i + k - 1] + nums[i + k])
        if dp[0][n - 1] >=(0.5 * sum(nums)):
            return True
        else:
            return False
# dp
class Solution:
    def PredictTheWinner(self, nums: List[int]) -> bool:
        n = len(nums)
        dp = [[0]*n for _ in range(n)]
        # 当面对的数组只有1个数时,先手的得分是nums[i],后手的得分是0,它们之间相差的最大分数是nums[i]
        for i in range(n):
            dp[i][i] = nums[i]
        # i依赖于i+1,所以递减
        for i in range(n-2, -1, -1):
            # j依赖于j-1,所以递增,同时j>i
            for j in range(i+1, n, 1):
                dp[i][j] = max( nums[i] - dp[i+1][j], nums[j] - dp[i][j-1])
        return dp[0][n-1] >= 0

488. 祖玛游戏

# 记忆+回溯
import functools
class Solution:
    def findMinStep(self, board: str, hand: str) -> int:
        codes = {"R": 10000, "Y": 1000, "B": 100, "G": 10, "W": 1}
        def encode(char_count):
            result = 0
            for c in char_count:
                result += codes[c] * char_count[c]
            return result
        def decode(value):
            chars = "WGBYR"
            idx = 0
            result = {"W": 0, "G": 0, "B": 0, "Y": 0, "R": 0}
            while value > 0:
                result[chars[idx]] = value % 10
                value //= 10
                idx += 1
            return result
        @functools.lru_cache(None)
        def findMin(board, hand_code):
            if not board:
                return 0
            steps = float("inf")
            hand_count = decode(hand_code)
            same_count = 1
            idx = 1
            while idx <= len(board):
                if idx == len(board) or board[idx] != board[idx - 1]:
                    last_char = board[idx - 1]
                    if same_count + hand_count[last_char] >= 3:
                        # 如果same_count大于等于3,那就让珠子自己消除,shoot为0
                        shoot = max(0, 3 - same_count)
                        # last_char对应的颜色用了多少颗减去相应的值
                        hand_count[last_char] -= shoot
                        # 子问题 + shoot = 当前问题的解
                        steps = min(steps, findMin(board[:idx - same_count] + board[idx:], encode(hand_count)) + shoot)
                        # 回溯
                        hand_count[last_char] += shoot
                    same_count = 1
                else:
                    same_count += 1
                idx += 1
            return steps
        hand_code = 0
        for c in hand:
            hand_code += codes[c]
        result = findMin(board, hand_code)
        return -1 if result == float("inf") else result
# 这题笔者还不会,先记录一个题解,留待后面回头再看

你可能感兴趣的:(leetcode)