leetcode 12.7-12.13

每日一题 861. 翻转矩阵后的得分

有一个二维矩阵 A 其中每个元素的值为 01
移动是指选择任一行或列,并转换该行或列中的每一个值:将所有 0 都更改为 1,将所有 1都更改为 0
在做出任意次数的移动后,将该矩阵的每一行都按照二进制数来解释,矩阵的得分就是这些数字的总和。
返回尽可能高的分数。

示例:
输入:[[0,0,1,1],[1,0,1,0],[1,1,0,0]]
输出:39
解释:
转换为 [[1,1,1,1],[1,0,0,1],[1,1,1,1]]
0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39

class Solution:
    def matrixScore(self, A: List[List[int]]) -> int:
        """
        矩阵仅仅变换行或者列,是的二进制最大。
        则通过行的移动,可以让每一行的第一个数为1,这样在第一列(最高位)最大;    
        其余列保证1的个数大于0的个数,保证其余列(次高位)最大。这样之和为最大。
        """
        if not A:
            return 0
        rows, columns = len(A), len(A[0])
        # 保证第一列全为1, 这样二进制数最大
        for x in A:
            if x[0] == 0:
                for i in range(columns):
                    x[i] = 0 if x[i] else 1
        # 其余列之和大于长度的一半,则表示1多于0,这样保证在高位的数大
        for j in range(1, columns):
            sum_col = sum(A[i][j] for i in range(rows))
            if sum_col < rows / 2:
                for i in range(rows):
                    A[i][j] = 0 if A[i][j] else 1
        # 求和
        ref = 0
        for i in range(rows):
            ref_row = 0
            for j in range(columns):
                ref_row=(ref_row<<1)+A[i][j]
            ref += ref_row
        return ref

每日一题842. 将数组拆分成斐波那契序列

给定一个数字字符串 S,比如 S = "123456579",我们可以将它分成斐波那契式的序列 [123, 456, 579]

形式上,斐波那契式序列是一个非负整数列表 F,且满足:

  • 0 <= F[i] <= 2^31 - 1,(也就是说,每个整数都符合 32 位有符号整数类型);
  • F.length >= 3
  • 对于所有的0 <= i < F.length - 2,都有 F[i] + F[i+1] = F[i+2] 成立。

另外,请注意,将字符串拆分成小块时,每个块的数字一定不要以零开头,除非这个块是数字 0 本身。

返回从 S 拆分出来的任意一组斐波那契式的序列块,如果不能拆分则返回 []

示例 1:
输入:"123456579"
输出:[123,456,579]

示例 2:
输入: "11235813"
输出: [1,1,2,3,5,8,13]

示例 3:
输入: "112358130"
输出: []
解释: 这项任务无法完成。

示例 4:
输入:"0123"
输出:[]
解释:每个块的数字不能以零开头,因此 "01","2","3" 不是有效答案。

示例 5:
输入: "1101111"
输出: [110, 1, 111]
解释: 输出 [11,0,11,11] 也同样被接受。

class Solution:
    def splitIntoFibonacci(self, S: str) -> List[int]:
        """
        官方解释
        回溯加裁剪: 裁剪规则为不合法的数,超界或者出现0开头两位数
        首先确定前两个数,存储到ref并查找之后的数
        当出现ref 两个数以上,且ref后两个数之和为当前数,ref存储当前数,并继续下去,如果不是则跳出,并去掉存储的ref
        并且重新确定前两个数。继续查找
        """
        ref = []
        m = 2**31 - 1
        def backtrack(index):
            if index == len(S):
                return len(ref) >= 3

            cur = 0
            for i in range(index, len(S)):
                if i > index and S[index] == '0':
                    return False
                cur = cur * 10 + ord(S[i]) - ord('0')
                if cur > m:
                    return False
                if len(ref) < 2 or cur == ref[-1] + ref[-2]:
                    ref.append(cur)
                    if backtrack(i+1):
                        # 一直查找,如果满足则返回True
                        return True
                    # 如果不满足,跳出,这一条的数列不行,则pop存储的数
                    ref.pop()
                elif len(ref) > 2 and cur > ref[-1] + ref[-2]:
                    return False
        backtrack(0)
        return ref

    # https://blog.csdn.net/Changxing_J/article/details/108079585    
    # 感谢大神提供思路
    def splitIntoFibonacci1(self, S: str) -> List[int]:
        """
        暴力法, 双重遍历所有列表中的元素, 首先判断是否合法,然后判断
        """
        N = len(S)

        # 判断数字是否合法
        def is_valid(n):
            return not (int(n) > 0 and n[0] == "0") and int(n) <= (2 ** 31 - 1)

        # 检查是否为斐波那契数列
        def is_fibonacci(m, n):
            if not is_valid(S[:m]) or not is_valid(S[m:n]):
                return False
            lst = [int(S[:m]), int(S[m:n])]
            idx1 = n
            while idx1 < N:
                nn = lst[-1] + lst[-2]  # 当前项
                s1 = str(nn)
                idx2 = idx1 + len(s1)
                s2 = S[idx1:idx2]
                if is_valid(s2) and s1 == s2:
                    lst.append(nn)
                    idx1 = idx2
                else:
                    return False
            return lst

        # 筛选所有的斐波那契数列
        for i in range(1, N):
            for j in range(i + 1, N):
                fibonacci_lst = is_fibonacci(i, j)
                if fibonacci_lst:
                    return fibonacci_lst
        return []

每日一题62. 不同路径

一个机器人位于一个 m x n网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?
示例 1:
输入:m = 3, n = 7
输出:28

示例 2:
输入:m = 3, n = 2
输出:3
解释:
从左上角开始,总共有 3 条路径可以到达右下角。

  1. 向右 -> 向右 -> 向下
  2. 向右 -> 向下 -> 向右
  3. 向下 -> 向右 -> 向右
class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        """
        dp思路, dp[i][j] 表示从[0][0] 开始到[i][j] 的路径
        最上面一行dp[0][i] = 1 , 最左边一列dp[i][0] = 1
        """
        if m == 1 or n == 1:
            return 1
        dp = [[1] * n] * m
        for i in range(1, m):
            for j in range(1, n):
                dp[i][j] = dp[i-1][j] + dp[i][j-1]
        return dp[m-1][n-1]

每日一题860. 柠檬水找零

在柠檬水摊上,每一杯柠檬水的售价为 5 美元。
顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。
每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。
注意,一开始你手头没有任何零钱。
如果你能给每位顾客正确找零,返回 true ,否则返回 false

示例 1:
输入:[5,5,5,10,20]
输出:true
解释:
前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。
第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。
第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。
由于所有客户都得到了正确的找零,所以我们输出 true。

class Solution:
    def lemonadeChange(self, bills: List[int]) -> bool:
        """
        保存5元, 10元, 20元的个数
        如果遇到20元,优先找5元和10元. 没有则找3个5元.
        """
        bill = {5: 0, 10:0, 20: 0}
        for x in bills:
            if x == 5:
                bill[x] += 1
            elif x == 10:
                if bill[5] < 1:
                    return False
                else:
                    bill[5] -= 1
                    bill[10] += 1
            else:
                if bill[10] > 0 and bill[5] > 0:
                    bill[5] -= 1
                    bill[10] -= 1
                    bill[20] += 1
                    continue
                elif bill[5] > 2:
                    bill[5] -= 3
                    bill[20] +=1
                else:
                    return False
        return True

每日一题649. Dota2 参议院

Dota2 的世界里有两个阵营:Radiant(天辉)和 Dire(夜魇)

Dota2 参议院由来自两派的参议员组成。现在参议院希望对一个 Dota2 游戏里的改变作出决定。他们以一个基于轮为过程的投票进行。在每一轮中,每一位参议员都可以行使两项权利中的**一**项:

  1. 禁止一名参议员的权利

    参议员可以让另一位参议员在这一轮和随后的几轮中丧失所有的权利

  2. 宣布胜利

    如果参议员发现有权利投票的参议员都是同一个阵营的,他可以宣布胜利并决定在游戏中的有关变化。

给定一个字符串代表每个参议员的阵营。字母 “R” 和 “D” 分别代表了 Radiant(天辉)和 Dire(夜魇)。然后,如果有 n 个参议员,给定字符串的大小将是 n

以轮为基础的过程从给定顺序的第一个参议员开始到最后一个参议员结束。这一过程将持续到投票结束。所有失去权利的参议员将在过程中被跳过。

假设每一位参议员都足够聪明,会为自己的政党做出最好的策略,你需要预测哪一方最终会宣布胜利并在 Dota2 游戏中决定改变。输出应该是 RadiantDire

class Solution:
    def predictPartyVictory(self, senate: str) -> str:
        """
        双队列, 分别记录R和D的顺序
        R在前就会让最前面的D失效. 自己进入下一轮, 添加到R的最后面
        """
        Radiant = [i for i, x in enumerate(senate) if x == 'R']
        Dire = [i for i, x in enumerate(senate) if x == 'D']

        while Radiant and Dire:
            if Radiant[0] < Dire[0]:
                Radiant.append(Radiant[0] + len(senate))
            else:
                Dire.append(Dire[0] + len(senate))
            Radiant.pop(0)
            Dire.pop(0)
        return 'Radiant' if len(Radiant) else 'Dire'

每日一题376. 摆动序列

如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。

例如,[1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3) 是正负交替出现的。相反, [1,4,7,2,5][1,7,4,5,5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。

给定一个整数序列,返回作为摆动序列的最长子序列的长度。 通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。

示例 1:
输入: [1,7,4,9,2,5]
输出: 6
解释: 整个序列均为摆动序列。

示例 2:
输入: [1,17,5,10,13,15,10,5,16,8]
输出: 7
解释: 这个序列包含几个长度为 7 摆动序列,其中一个可为[1,17,10,13,10,16,8]。

示例 3:
输入: [1,2,3,4,5,6,7,8,9]
输出: 2

class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        '''
        2个dp,
        一个记录上扬摆动序列,一个记录下降摆动序列.
        '''
        if not nums:
            return 0
        down = [1 for _ in range(len(nums))]
        up = [1 for _ in range(len(nums))]
        for i in range(1, len(nums)):
            for j in range(i):
                # i和之前的数j 逐个比较,如果比他大,更新i的上扬序列,为j的上扬序列和j的下降序列+1之中的最大值。
                if nums[i] > nums[j]:
                    up[i] = max(up[i], down[j] + 1)
                elif nums[i] < nums[j]:
                    down[i] = max(down[i], up[j] + 1)
        return max(max(down), max(up))

进阶算法

class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        '''
        记录每个数和前面的差值,
        小于0表示比前面的小,大于0表示比前面的数大
        出现连续正数或者连续负数对于最大摆动序列长度没有任何影响,
        假如出现连续正数,则第一个正数记录最长上扬序列长度,后面的也是正数,只会影响上扬序列长度,
        影响不了下降序列长度.
        '''
        n=len(nums)
        if n<2:return n
        a=[nums[i+1]-nums[i] for i in range(n-1)]
        up=down=1
        for i in a:
            if i>0:
                up=down+1
            elif i<0:
                down=up+1
        return max(up,down)

每日一题217. 存在重复元素

给定一个整数数组,判断是否存在重复元素。

如果任意一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false

示例 1:
输入: [1,2,3,1]
输出: true

示例 2:
输入: [1,2,3,4]
输出: false

示例 3:
输入: [1,1,1,3,3,4,3,2,4,2]
输出: true

class Solution:
    def containsDuplicate(self, nums: List[int]) -> bool:
        '''
        set 集合里的元素具有唯一性
        如果有重复则输出True
        一行代码
        return len(nums) != len(set(nums))
        '''
        if not nums:
            return False
        x = set()
        for num in nums:
            if num in x:
                return True
            else:
                x.add(num)
        return False

因课题原因,前面一段时间未更新,会补更。
在飞的小猪

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,194评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,058评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,780评论 0 346
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,388评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,430评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,764评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,907评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,679评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,122评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,459评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,605评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,270评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,867评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,734评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,961评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,297评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,472评论 2 348

推荐阅读更多精彩内容