2024.3.16力扣(<=1200)刷题记录

一、1920. 基于排列构建数组

1.遍历,虽然返回数组不算在时复里面,但是还是感觉和时复O(1)的有区别。代码如下:

class Solution:
    def buildArray(self, nums: List[int]) -> List[int]:
        # 遍历 时复n,空复n
        ans = [0]*len(nums)
        for i in range(len(nums)):
            ans[i] = nums[nums[i]]
        return ans

2.原地构建,参考官方题解(. - 力扣(LeetCode)),空复为O(1)。这个方法很妙,博主不是没有想过原地构建,但是储存原数字成了问题,这个方法能够很妙的同时储存原数据和新数据。代码如下:

class Solution:
    def buildArray(self, nums: List[int]) -> List[int]:
        # 原地构建 1000进制
        for i in range(len(nums)):
            nums[i] += 1000*(nums[nums[i]] % 1000)
        for i in range(len(nums)):
            nums[i] //= 1000
        return nums

3.原地构建1000进制数改进,len(nums)进制数,因为数组元素0 <= nums[i] < nums.length

。方法来自另一题解(. - 力扣(LeetCode))。代码如下:

class Solution:
    def buildArray(self, nums: List[int]) -> List[int]:
        # 原地构建 n进制
        n = len(nums)
        for i in range(n):
            nums[i] += nums[nums[i]] % n * n
            # nums[i] += n*(nums[nums[i]] % n)
        for i in range(n):
            nums[i] //= n
        return nums

 4.一行代码,快速生成列表法。方法来自另一题解(. - 力扣(LeetCode))。代码如下:

class Solution:
    def buildArray(self, nums: List[int]) -> List[int]:
        # 一行
        return [nums[nums[i]] for i in range(len(nums))]

 二、961. 在长度 2N 的数组中找出重复 N 次的元素

1.排序

class Solution:
    def repeatedNTimes(self, nums: List[int]) -> int:
        # 其他元素恰好只出现一次
        # 排序,时复O(nlogn),空复O(1)
        nums.sort()
        for i in range(1,len(nums)):
            if nums[i] == nums[i-1]:
                return nums[i]

2.遍历+哈希表

class Solution:
    def repeatedNTimes(self, nums: List[int]) -> int:
        # 其他元素恰好只出现一次
        # 遍历+哈希表 时复O(n),空复O(n)
        hash = {}
        for x in nums:
            if hash.get(x,0) == 1:
                return x
            hash[x] = hash.get(x,0) + 1

3.数学方法,总结间隔规律,方法来自官方题解(. - 力扣(LeetCode))。

class Solution:
    def repeatedNTimes(self, nums: List[int]) -> int:
        # 其他元素恰好只出现一次
        # 数学方法
        n = len(nums)
        for gap in range(1,4):
            for i in range(n-gap):
                if nums[i] == nums[i+gap]:
                    return nums[i]
        return -1

4.随机选择,注意时复期望为O(1),方法来自官方题解。这种解法挺新奇的。

class Solution:
    def repeatedNTimes(self, nums: List[int]) -> int:
        # 其他元素恰好只出现一次
        # 随机选择
        n = len(nums)
        while True:
            x,y = random.randrange(n),random.randrange(n)
            if x!=y and nums[x] == nums[y]:
                return nums[x]

三、2278. 字母在字符串中的百分比

1.遍历

class Solution:
    def percentageLetter(self, s: str, letter: str) -> int:
        # 遍历
        ans = 0
        for c in s:
            if c == letter:
                ans += 1
        return math.floor(ans / len(s) * 100)

2.count函数

class Solution:
    def percentageLetter(self, s: str, letter: str) -> int:
        # count函数
        # return math.floor(s.count(letter) / len(s) * 100)
        return s.count(letter)* 100// len(s)

 四、1342. 将数字变成 0 的操作次数

1.位运算

class Solution:
    def numberOfSteps(self, num: int) -> int:
        ans = 0
        #当最后数字为1时,不需要除二但是循环内ans会多加一,所以在这里提前减一,避免循环多次判断
        if num != 0:    
            ans -= 1
        while num:
            ans += num & 1      
            #奇数-1位数不变,但操作数要+1,然后变成了偶数,又要右移一下,总括操作数+2
            num >>= 1          
             #偶数/2位数要变,操作数要加1
            ans += 1
        return ans

2.二进制字符串。omg这个方法惊到我了,我虽然有想到和二进制有关,所以写的位运算,但是我没有想到转换为字符串。并且这个写法好新奇,我从没见过,多学习学习。方法来自题解(. - 力扣(LeetCode))。

class Solution:
    def numberOfSteps(self, num: int) -> int:
        # 二进制字符串
        return len(b:=bin(num)[2:]) + b.count("1") - 1

来自chatgpt的解释:

这段代码使用了 Python 3.8 中添加的海象运算符(walrus operator),即 :=。让我来解释一下这段代码的含义:

  1. bin(num):将整数 num 转换为二进制表示的字符串。
  2. [2:]:取二进制字符串的子串,去掉开头的 '0b'。
  3. b:=:使用海象运算符,将二进制字符串赋值给变量 b 的同时,也返回这个值。
  4. len(b):计算二进制字符串的长度。
  5. b.count('1'):统计二进制字符串中 '1' 的个数。
  6. len(b) + b.count('1') - 1:二进制字符串的长度加上 '1' 的个数再减去1,得到的结果就是所求的步数。

因此,这段代码的作用是计算将给定的整数转换为 0 需要的步数。步数的计算方法是将该整数转换为二进制表示,然后计算其长度加上 '1' 的个数再减去1。

感谢你看到这里!一起加油吧!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值