前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode笔记:Weekly Contest 241 比赛记录

LeetCode笔记:Weekly Contest 241 比赛记录

作者头像
codename_cys
发布2021-05-19 14:28:56
4400
发布2021-05-19 14:28:56
举报
文章被收录于专栏:我的充电站

0. 赛后总结

如上一个博客所述,这周的比赛其实因为一些琐事没能参加,只是赛后做了一下比赛的题目,这里就大致记录一下吧。

1. 题目一

给出题目一的试题链接如下:

1. 解题思路

这一题我的解法其实很暴力,就是彻底的暴力求解,把所有的 2 n 2^n 2n种可能性全部计算一下,然后就能够得到最终的答案了。

2. 代码实现

给出python代码实现如下:

代码语言:javascript
复制
class Solution:
    def subsetXORSum(self, nums: List[int]) -> int:
        n = len(nums)
        res = 0
        for item in product(range(2), repeat=n):
            s = 0
            for flag, k in zip(item, nums):
                if flag == 1:
                    s = s ^ k
            res += s
        return res

提交代码评测得到:耗时148ms,占用内存14MB。

2. 题目二

给出题目二的试题链接如下:

1. 解题思路

这一题我这边的思路其实也挺暴力的,要能够完成这种变换,那么0和1的数目就必须满足差值最多只能为1,然后最终的字符排列就是确定的,由此,我们统计一下原始字符串与最终目标字符串之间的差异字符数目就可以最终给出需要交换的次数。

2. 代码实现

给出python代码实现如下:

代码语言:javascript
复制
class Solution:
    def minSwaps(self, s: str) -> int:
        cnt = Counter(s)
        def count_diff(s1, s2):
            cnt = 0
            for c1, c2 in zip(s1, s2):
                if c1 != c2:
                    cnt += 1
            return cnt // 2
        
        if abs(cnt["0"] - cnt["1"]) > 1:
            return -1
        elif cnt['0'] == cnt['1'] + 1:
            return count_diff("0" + "10" * (len(s) // 2), s)
        elif cnt["0"] == cnt['1'] - 1:
            return count_diff("1" + "01" * (len(s) // 2), s)
        else:
            return min(count_diff("10" * (len(s) // 2), s), count_diff("01" * (len(s) // 2), s))

提交代码评测得到:耗时24ms,占用内存14.3MB。

3. 题目三

给出题目三的试题链接如下:

1. 解题思路

这一题我给出的结构其实不算多么巧妙,就是用两个字典结构保存nums1和nums2,然后为了保留index信息,在单独保存一下nums2,然后后面的add操作的算法复杂度就是O(1),然后count的算法复杂度就是O(N_1)

2. 代码实现

给出python代码实现如下:

代码语言:javascript
复制
class FindSumPairs:

    def __init__(self, nums1: List[int], nums2: List[int]):
        self.nums1_cnt = Counter(nums1)
        self.nums1_elems = sorted(self.nums1_cnt.keys())
        self.nums2 = nums2
        self.nums2_cnt = Counter(nums2)
        

    def add(self, index: int, val: int) -> None:
        x = self.nums2[index]
        self.nums2_cnt[x] -= 1
        self.nums2[index] += val
        self.nums2_cnt[x+val] += 1

    def count(self, tot: int) -> int:
        res = 0
        for k in self.nums1_elems:
            if k >= tot:
                break
            res += self.nums1_cnt[k] * self.nums2_cnt[tot-k]
        return res

提交代码评测得到:耗时816ms,占用内存44.4MB。

4. 题目四

给出题目四的试题链接如下:

1. 解题思路

这次的第四题坦率地说有点一言难尽,怎么说呢,思路一开始就很明确,就是动态规划,然后就是考虑递推公式,然后就是想了一下午都没有想出来,但是看了一下答案之后发现简直简单的离谱,原因就是换个角度思考问题就行。

我们先给出递推公式如下:

f(n,k)的定义就是题目中的定义,就是n个数,然后可见的数为k个。

但是,我们考察迭代公式的时候,不要去考虑加入一个最大的数,而是应该考虑将原始的排列中所有的数字加1,然后加入一个最小的数,此时,需要考虑的前一种 k 的可能性只能为 k 或者 k−1,我们分别这两种情况:

  1. 如果原来暴露的数刚好就是k个时,我们能够加入的位置就一定是除了第一个位置之外所有的位置,所以此时的排列数目就是 (n-1) \times f(n-1, k) ;
  2. 如果原来暴露的数目为k-1时,此时我们就必须将这个最小数加入到第一个数的位置,此时的所有可能性为: f(n-1, k-1)

结合上述两种情况,我们即可得到最终的递推公式。

2. 代码实现

给出python代码实现如下:

代码语言:javascript
复制
class Solution:
    def rearrangeSticks(self, n: int, k: int) -> int:
        MOD = 10**9+7
        
        dp = [[0 for _ in range(k+1)] for _ in range(n+1)]
        dp[1][1] = 1
        for i in range(n):
            for j in range(min(k, i+1)):
                if i == 0 and j == 0:
                    continue
                dp[i+1][j+1] = (dp[i][j] + i * dp[i][j+1]) % MOD
                
        return dp[n][k]

提交代码评测得到:耗时2548ms,占用内存38.6MB。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/05/17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0. 赛后总结
  • 1. 题目一
    • 1. 解题思路
      • 2. 代码实现
      • 2. 题目二
        • 1. 解题思路
          • 2. 代码实现
          • 3. 题目三
            • 1. 解题思路
              • 2. 代码实现
              • 4. 题目四
                • 1. 解题思路
                  • 2. 代码实现
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档