力扣周赛341题解

77 阅读3分钟

6376. 一最多的行

这道题目的要求是给定一个二维矩阵,其中只包含0和1,找出其中包含1最多的行,并返回该行的索引和1的个数。如果有多个行满足条件,返回索引最小的那个。

我的思路是遍历一次矩阵,用一个字典记录每一行的1的个数,并用一个变量记录当前最大的1的个数。然后再遍历一次字典,找出满足条件的行,并返回结果。

我的代码如下:

def rowAndMaximumOnes(mat):
    # 初始化字典和最大值
    dic = {}
    max_ones = 0
    # 遍历矩阵
    for i in range(len(mat)):
        # 统计每一行的1的个数
        count = 0
        for j in range(len(mat[0])):
            if mat[i][j] == 1:
                count += 1
        # 更新字典和最大值
        dic[i] = count
        max_ones = max(max_ones, count)
    # 初始化结果
    res = [-1, -1]
    # 遍历字典
    for key, value in dic.items():
        # 如果当前行满足条件
        if value == max_ones:
            # 如果结果为空或者当前行索引更小
            if res[0] == -1 or key < res[0]:
                # 更新结果
                res = [key, value]
    # 返回结果
    return res

6350. 找出可整除性得分最大的整数

这道题目的要求是给定一个整数数组和一个除数数组,找出除数数组中能被整数数组中所有元素整除的整数,并返回其可整除性得分。可整除性得分定义为能被整除的元素个数乘以该元素。如果有多个整数满足条件,返回其中最小的那个。

我的思路是遍历一次除数数组,用一个数组记录每个除数对应的可整除性得分,并用一个变量记录当前最大的可整除性得分。然后再遍历一次数组,找出满足条件的除数,并返回结果。

我的代码如下:

def maxDivScore(nums, divisors):
    # 初始化数组和最大值
    score = [0] * len(divisors)
    max_score = 0
    # 遍历除数数组
    for i in range(len(divisors)):
        # 遍历整数数组
        for num in nums:
            # 如果能被整除
            if num % divisors[i] == 0:
                # 更新可整除性得分和最大值
                score[i] += num
                max_score = max(max_score, score[i])
    # 初始化结果
    res = -1
    # 遍历数组
    for i in range(len(score)):
        # 如果当前除数满足条件
        if score[i] == max_score:
            # 如果结果为空或者当前除数更小
            if res == -1 or divisors[i] < res:
                # 更新结果
                res = divisors[i]
    # 返回结果
    return res

6375. 构造有效字符串的最少插入数

这道题目的要求是给定一个字符串,其中只包含a, b, c三种字符,找出最少需要插入多少个字符,使得字符串变成有效的。有效的定义是字符串中不存在连续的三个相同字符,且字符串中每个字符的个数都是3的倍数。

我的思路是遍历一次字符串,模拟插入过程,针对不同的字符情况判断需要插入多少个字符,并用一个变量记录总的插入数。具体的判断规则如下:

  • 如果当前字符是a,那么有以下几种情况:
    • 如果当前字符是字符串的最后一个字符,那么需要插入两个b或者c,使得字符串以abc或者acb结尾。
    • 如果下一个字符也是a,那么需要插入两个b或者c,使得字符串中不存在连续的三个a。
    • 如果下一个字符是c,那么需要插入一个b,使得字符串中每个字符的个数都是3的倍数。
  • 如果当前字符是b,那么有以下几种情况:
    • 如果当前字符是字符串的最后一个字符,那么需要插入一个a或者c,使得字符串以aba或者cbc结尾。
    • 如果下一个字符是a,那么需要插入一个c,使得字符串中每个字符的个数都是3的倍数。
    • 如果下一个字符是b,那么需要插入两个a或者c,使得字符串中不存在连续的三个b。
  • 如果当前字符是c,那么有以下几种情况:
    • 如果当前字符是字符串的最后一个字符,那么不需要插入任何字符。
    • 如果下一个字符是c,那么需要插入两个a或者b,使得字符串中不存在连续的三个c。
    • 如果下一个字符是b,那么需要插入一个a,使得字符串中每个字符的个数都是3的倍数。

我的代码如下:

def addMinimum(word):
    # 初始化数组和结果
    array = list(word)
    n = len(array)
    ans = 0
    # 处理头部
    if array[0] == 'b':
        ans += 1
    elif array[0] == 'c':
        ans += 2
    # 遍历字符串
    for i in range(n):
        # 根据不同的字符情况判断
        if array[i] == 'a':
            if i + 1 >= n:
                ans += 2
            elif array[i + 1] == 'a':
                ans += 2
            elif array[i + 1] == 'c':
                ans += 1
        elif array[i] == 'b':
            if i + 1 >= n:
                ans += 1
            elif array[i + 1] == 'a':
                ans += 1
            elif array[i + 1] == 'b':
                ans += 2
        elif array[i] == 'c':
            if i + 1 >= n:
                ans += 0
            elif array[i + 1] == 'c':
                ans += 2
            elif array[i + 1] == 'b':
                ans += 1
    # 返回结果
    return ans

6378. 最小化旅行的价格总和

这道题目的要求是给定一张无向图和一些城市之间的价格信息,找出从第0号城市出发到第n-1号城市结束,并且经过所有城市恰好一次的最小价格总和。如果不存在这样的路径,返回-1。

我的思路是使用动态规划和状态压缩来解决这道题目。具体地:

  • 定义状态dp[i][j]表示从第0号城市出发,经过状态i中的城市,并且以第j号城市为终点的最小价格总和。状态i是一个二进制数,表示哪些城市已经访问过,例如i=10101表示访问过第0、2、4号城市。
  • 定义转移方程dp[i][j] = min(dp[i][j], dp[i - (1 << j)][k] + cost[k][j]),其中k是状态i中除了j之外的任意一个城市,cost[k][j]表示从第k号城市到第j号城市的价格。这个方程的含义是,要得到状态i和终点j的最小价格总和,需要枚举上一个状态i - (1 << j)和上一个终点k,并加上从k到j的价格,取最小值。
  • 定义初始状态dp[1 << j][j] = cost[0][j],表示只访问过第0号和第j号城市,并且以第j号城市为终点的最小价格总和,等于从第0号城市到第j号城市的价格。
  • 定义目标状态dp[(1 << n) - 1][n - 1],表示从第0号城市出发,经过所有城市,并且以第n-1号城市为终点的最小价格总和。

我的代码如下:

def minimizeTravelCost(n, edges, cost):
    # 初始化动态规划数组
    dp = [[float('inf')] * n for _ in range(1 << n)]
    # 初始化初始状态
    for j in range(1, n):
        dp[1 << j][j] = cost[0][j]
    # 遍历所有状态
    for i in range(1, 1 << n):
        # 遍历所有终点
        for j in range(n):
            # 如果当前状态包含当前终点
            if i & (1 << j):
                # 遍历所有上一个终点
                for k in range(n):
                    # 如果上一个状态包含上一个终点
                    if i & (1 << k) and k != j:
                        # 更新转移方程
                        dp[i][j] = min(dp[i][j], dp[i - (1 << j)][k] + cost[k][j])
    # 返回目标状态
    return dp[(1 << n) - 1][n - 1] if dp[(1 << n) - 1][n - 1] != float('inf') else -1