1007 行相等的最少多米诺旋转(字典记录数字出现的位置、贪心)

1. 问题描述:

在一排多米诺骨牌中,A[i] 和 B[i] 分别代表第 i 个多米诺骨牌的上半部分和下半部分。(一个多米诺是两个从 1 到 6 的数字同列平铺形成的 —— 该平铺的每一半上都有一个数字。)
我们可以旋转第 i 张多米诺,使得 A[i] 和 B[i] 的值交换。返回能使 A 中所有值或者 B 中所有值都相同的最小旋转次数。如果无法做到,返回 -1.

示例 1:

输入:A = [2,1,2,4,2,2], B = [5,2,6,2,3,2]
输出:2
解释:
图一表示:在我们旋转之前, A 和 B 给出的多米诺牌。
如果我们旋转第二个和第四个多米诺骨牌,我们可以使上面一行中的每个值都等于 2,如图二所示。

示例 2:

输入:A = [3,5,1,2,3], B = [3,6,3,3,4]
输出:-1
解释:
在这种情况下,不可能旋转多米诺牌使一行的值相等。

提示:

  1. 1 <= A[i], B[i] <= 6
  2. 2 <= A.length == B.length <= 20000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-domino-rotations-for-equal-row

2. 思路分析:

① 因为最终需要判断A或者B中牌通过旋转之后的全部值是否是相等的,所以一开始想到的是哈希表(字典)来记录各个数字出现的位置,可以声明两个字典来分别统计A与B中1-6数字出现的位置,求解他们的并集判断并集的长度是否大于等于A的长度,假如相等说明是可以通过翻转使得最终牌的所有元素是相等的,然后我们求解两个字典记录的当前数字出现位置的交集,因为这些位置是不需要通过交换的,在求解最短长度的时候就可以减去不需要交换的位置的长度从而得到较短的旋转次数

② 除了①中的方法之外,还可以使用贪心的思路解决(感觉有的时候需要多思考一下可能会想到更优的解决思路),我们知道最终A或者B的牌通过翻转之后全部元素可能是相等的,所以我们只需要判断A或者B中的第一张牌是否能够通过翻转使得最终的元素全部是相等的即可,因为第一张牌不可以翻转得到那么最终肯定不能够是否全部牌是相等的,想清楚这一点剩下来的就简单了

3. 代码如下:

两个字典记录数字出现的位置:

import collections
from typing import List


class Solution:
    def minDominoRotations(self, A: List[int], B: List[int]) -> int:
        dicA, dicB = collections.defaultdict(list), collections.defaultdict(list)
        # 字典分别记录数字出现的位置
        for i in range(len(A)):
            dicA[A[i]].append(i)
            dicB[B[i]].append(i)
        res = len(A) + 1
        for i in range(1, 7):
            if i in dicA:
                n1, n2 = dicA[i], dicB[i]
                if len(set(n1 + n2)) >= len(A):
                    # 求解两个集合的交集
                    l = list(set(n1) & set(n2))
                    # 减去不需要交换元素的长度
                    res = min(res, len(n1) - len(l), len(n2) - len(l))
        return -1 if res == len(A) + 1 else res

官方贪心代码:

from typing import List


class Solution:
    def minDominoRotations(self, A: List[int], B: List[int]) -> int:
        def check(x):
            rotations_a = rotations_b = 0
            for i in range(n):
                if A[i] != x and B[i] != x:
                    return -1
                elif A[i] != x:
                    rotations_a += 1
                elif B[i] != x:
                    rotations_b += 1
            return min(rotations_a, rotations_b)
        n = len(A)
        rotations = check(A[0])
        if rotations != -1 or A[0] == B[0]:
            return rotations
        else:
            return check(B[0])

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于vue健身小程序正是采用微信小程序和网络设计的新型系统,可以有效的把健身信息与网络相结合,为用户提供工作帮助和管理需求。本系统采用mysql数据库存储数据,兼容性更强,可跨越多种平台,采用的框架为ssm。主要设计的内容包括课程信息、教练信息、健身视频。教练可以上传健身视频,学员可以购买课程和预约教练以及在线充值、发帖。为了可以给用户更多的提醒,本系统中加入了当前登录角色的提示内容。管理员在系统中可以更新各种数据信息。本系统是信息化社会发展的必然产物,可以为用户提供更为高效的管理以及辅助,同时也可以改变健身房管理的局面,提高效率。 登录功能为管理员、教练和学员登录,在登录界面设计中包括用户名和密码、权限的检验。用户名和密码、权限的检验过程由数据库自动完成,此过程需要1秒左右。首先由用户填写账号和密码,选择权限,然后点击登录系统,数据库自对用户名和密码进对比,所填写数据正确方能进登录,所填写数据错误则需要返回登录界面重新登录。首页界面是最直接的展示,用户可以对系统进最直接的了解。在本功能界面里可以看到背景图片、功能导航栏,视频信息、课程信息、教练信息等。学员信息是健身房的重要组成部分,管理员可以添加学员信息,查询学员信息.。教练信息管理功能分为管理员管理教练信息和登记、查询教练信息,管理员可以看到教练的各项基本信息,可以删除教练的基本信息。系统里展示的健身视频都可以由管理员进审核和添加管理,教练也可以发布视频。管理员可以输入视频名称和上传视频来实现健身视频的添加。管理员和教练可以上传培训课程,学员可以浏览课程信息。管理员和教练都可以管理预约信息,学员在看到教练后可以进预约。管理员可以审核帖子信息。管理员、教练和学员都可以管理订单信息。学员在课程详情里可以购买课程。学员在教练详情里可以评价、收藏以及预约。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值