2024.3.14力扣刷题记录

一、2351. 第一个出现两次的字母

1.哈希数组,空间复杂度:O(∣Σ∣)(其中 Σ是字符集)。

class Solution:
    def repeatedCharacter(self, s: str) -> str:
        # 哈希表
        hash = [0]*26
        for c in s:
            if hash[ord(c)-ord('a')] == 1:
                return c
            hash[ord(c)-ord('a')] = 1

2.状态压缩,空间复杂度:O(1)。方法参考官方题解(. - 力扣(LeetCode))。因为字母一共有26个,可以使用一个32位二进制数储存,从而达到降低空间复杂度的目的。

class Solution:
    def repeatedCharacter(self, s: str) -> str:
        # 状态压缩
        seen = 0
        for c in s:
            if seen & (1 << (ord(c)-ord('a')) ):
                return c
            seen |= (1 << (ord(c)-ord('a')) )

二、2903. 找出满足差值条件的下标 I

1.遍历

class Solution:
    def findIndices(self, nums: List[int], indexDifference: int, valueDifference: int) -> List[int]:
        # 遍历
        # 设i <= j
        for i in range(len(nums)):
            for j in range(i+indexDifference,len(nums)):
                if abs(nums[i]-nums[j]) >= valueDifference:
                    return [i,j]
        return [-1,-1]

2. 双指针

学习一下灵神的方法(. - 力扣(LeetCode))。这里直接令i=j-indexDifference,而没有遍历。是因为通过移动j来达到遍历i的效果,所以不用遍历,但是需要维护以达到不同i和j的组合。这个方法太妙了,时复为O(n)。

class Solution:
    def findIndices(self, nums: List[int], indexDifference: int, valueDifference: int) -> List[int]:
        # 双指针
        max_idx = min_idx = 0
        for j in range(indexDifference,len(nums)):
            i = j-indexDifference   # 通过移动j来达到遍历i的效果,所以需要维护
            if nums[i] > nums[max_idx]:
                max_idx = i
            elif nums[i] < nums[min_idx]:
                min_idx = i
            if nums[max_idx] - nums[j] >= valueDifference:
                return [max_idx,j]
            if nums[j] - nums[min_idx] >= valueDifference:
                return [min_idx,j]
        return [-1,-1]

三、2824. 统计和小于目标的下标对数目

相向双指针,解法参考(. - 力扣(LeetCode))。代码如下:

class Solution:
    def countPairs(self, nums: List[int], target: int) -> int:
        # 相向双指针
        nums.sort()
        ans = 0
        if nums[-1] + nums[-2] < target:    #优化
            return len(nums)*(len(nums)-1)//2
        if nums[0] + nums[1] >= target:
            return 0
        l,r = 0,len(nums)-1
        while l<r:
            if nums[l] + nums[r] < target:
                ans += r-l
                l += 1
            else:
                r -= 1
        return ans

四、16. 最接近的三数之和

运用排序+指针,将绝对值转化为大于小于两个区间,同时算两个值,再进行比较。

class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        # 排序+指针
        nums.sort()
        ans1,ans2 = -inf,inf
        if sum(nums[:3]) >= target:
            return sum(nums[:3])
        if sum(nums[-1:-4:-1]) <= target:
            return sum(nums[-1:-4:-1])
        
        for i in range(len(nums)-2):
            j,k = i+1,len(nums)-1
            while i<j<k:
                cur = nums[i]+nums[j]+nums[k]
                if cur == target:
                    return target
                if cur > target:
                    ans2 = min(ans2,cur)# 求和大于target的最小和
                    k -= 1
                else:
                    ans1 = max(ans1,cur)# 求和小于target的最大和
                    j += 1
        return ans1 if target-ans1 < ans2 - target else ans2

根据灵神题解(. - 力扣(LeetCode)),添加三个优化:

class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        # 排序+指针
        nums.sort()
        ans1,ans2 = -inf,inf
        if sum(nums[:3]) >= target:
            return sum(nums[:3])
        if sum(nums[-1:-4:-1]) <= target:
            return sum(nums[-1:-4:-1])
        
        for i in range(len(nums)-2):
            if i and nums[i] == nums[i-1]:
                continue    #优化三
            
            if sum(nums[i:i+3]) > target:
                ans2 = min(ans2,sum(nums[i:i+3]) )
                break       #优化一

            if nums[i] + nums[len(nums)-2] + nums[len(nums)-1] < target:
                ans1 = max(ans1,(nums[i] + nums[len(nums)-2] + nums[len(nums)-1]) )
                continue    #优化二  

            j,k = i+1,len(nums)-1
            while i<j<k:
                cur = nums[i]+nums[j]+nums[k]
                if cur == target:
                    return target
                if cur > target:
                    ans2 = min(ans2,cur)# 求和大于target的最小和
                    k -= 1
                else:
                    ans1 = max(ans1,cur)# 求和小于target的最大和
                    j += 1
        return ans1 if target-ans1 < ans2 - target else ans2

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值