leetcode 虚拟竞赛 Weekly Contest 91

每天坚持刷题!!PS:昨个竟然忘了上传…
本人菜鸟只在规定时间做了三道…代码有些乱因为看着时间流逝有些慌了…

题目一:
860. 柠檬水找零

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

题目分析:
1. 因为顾客只可能给你5, 10, 20刀的钞票,因此只需要考虑自己手里有多少10元和5元的钞票即可(用个哈希表存储即可),要注意的是如果没有10元钞票可以用5元钞票代替,因此我们在有10元钞票时优先给10元钞票,没有在给5元。

2 非常简单只需要考虑客户给的钞票分别是5, 10, 20的情况就好,5元就直接手下,10元看手里有没有5元,20元先看自己手里有没有10元钞票,有再看有没有5元,没有10元钞票看手机有没有足够的5元钞票即可

class Solution(object):
    def lemonadeChange(self, bills):
        """
        :type bills: List[int]
        :rtype: bool
        """
        if not bills:
            return True
        result = True
        temp_dict = {5:0, 10:0}
        for bill in bills:
            if bill == 5:
                temp_dict[5] += 1
            elif bill == 10:
                if temp_dict[5] == 0:
                    result = False
                    break
                else:
                    temp_dict[5] -= 1
                    temp_dict[10] += 1
            elif bill == 20:
                if temp_dict[5] == 0:
                    result = False
                    break
                else:
                    if temp_dict[10] == 0:
                        if temp_dict[5] >= 3:
                            temp_dict[5] -= 3
                        else:
                            result = False
                            break
                    else:
                        temp_dict[5] -= 1
                        temp_dict[10] -= 1
        return result

题目二:
863. 二叉树中所有距离为 K 的结点

题目描述:
给定一个二叉树(具有根结点 root), 一个目标结点 target ,和一个整数值 K 。返回到目标结点 target 距离为 K 的所有结点的值的列表。 答案可以以任何顺序返回。

题目分析:
这道题考二叉树,距离的概念可以把二叉树看做一个图就好理解了。我的思路分两块,一个是先找到这个节点(我用的先序遍历),二是遍历寻找节点时使用数组存储所有路径上的节点,最后一个元素是目标节点,然后从后往前遍历数组,用DFS寻找距离为K,K-1, K-2… 0的节点即可,注意不能往回找到数组里面的节点,因此在DFS中要设置障碍点。举例来说:假如我在目标节点的父节点出找寻距离为1的节点,此时的距离1已经是真正的目标距离减去父节点到目标节点的距离(1)

class Solution(object):
    def distanceK(self, root, target, K):
        """
        :type root: TreeNode
        :type target: TreeNode
        :type K: int
        :rtype: List[int]
        """
        if not root or target is None or K is None:
            return []
        result = []
        def recur_find_target(root, target, t_list, final):
            if not root:
                return []
            t_list.append(root)
            if root == target:
                for i in t_list:
                    final.append(i)
                return final
            recur_find_target(root.left, target, [d for d in t_list], final)
            recur_find_target(root.right, target, [d for d in t_list], final)
            return final
        temp_list =recur_find_target(root, target, [], [])
        def dps(root, tt_list, dist, ee):
            if not root:
                return []
            if root == ee:
                return []
            if dist == 0:
                tt_list.append(root.val)
                return [d for d in tt_list]
            tt_list += dps(root.left, [], dist - 1, ee)
            tt_list += dps(root.right, [], dist - 1, ee)
            return tt_list

        if K == 0:
            result.append(temp_list[-1].val)
            return result
        for i in xrange(len(temp_list) - 1, -1, -1):
            dist = K + i - (len(temp_list) - 1)
            if dist == 0:
                result.append(temp_list[i].val)
                break
            ee = temp_list[i + 1] if i + 1 <= len(temp_list) - 1 else None
            result += dps(temp_list[i], [], dist, ee)
        return result

题目三:
861. 翻转矩阵后的得分

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

题目分析:
1. 这个题目一开始第一眼以为是DP,结果稍加分析发现太麻烦了,因为不限制次数也不限制是行翻转还是列翻转,而且同一行或者同一列可以翻转无数次。那么下意识就觉得能解决的方法就只有贪心法了。
2. 因为有列和行两个维度,因此我们可以先对每一行判定是否要翻转,然后在对矩阵的每一列判定是否需要翻转即可

class Solution(object):
    def matrixScore(self, A):
        """
        :type A: List[List[int]]
        :rtype: int
        """
        if not A:
            return 0
        if len(A) == 1 and len(A[0]) == 1:
            return 1
        def cal_val(ll, ):
            i = 0
            result = 0
            for ii in xrange(len(ll) - 1, -1, -1):
                result += 2 ** i if ll[ii] == 1 else 0
                i += 1
            return result
        def rever(ll):
            result = []
            for i in ll:
                temp = 1 if i == 0 else 0
                result.append(temp)
            return result
        for i in xrange(len(A)):
            if cal_val(rever(A[i])) > cal_val(A[i]):
                A[i] = rever(A[i])
        for j in xrange(len(A[0])):
            temp = [d[j] for d in A]
            if len([d for d in temp if d == 0]) > len([d for d in temp if d == 1]):
                for i in xrange(len(A)):
                    A[i][j] = 1 if A[i][j] == 0 else 0
        result = 0
        for i in xrange(len(A)):
            result += cal_val(A[i])
        return result

欢迎一起讨论!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值