内置模块及函数、两数之和(|、||)、贪心算法(情侣牵手)

本文探讨了贪心算法在情侣牵手、盛最多水容器和接雨水等问题中的应用,以及如何结合双指针技巧优化求解过程。通过实例演示了哈希表、二分查找和双指针在两数之和、最大面积和雨水收集中的高效使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文引用力扣大佬题解贪心部分大佬题解

一、内置模块及函数

# datetime 
from datetime import datetime,timedelta
start_time=datetime(year=1000,month=1,day=1)
end_time=datetime(year=,month=,day=)
delta_time=timedelta(days=)
while start_time<=end_time:
    if ...:
        operation 
    start_time+=delta_time
print(...)
#全排列 itertools.permutations
#题目:给定一个不含重复数字的数组nums,返回其所有可能的全排列,你可以按任意顺序返回答案
class Solution:
    def permute(self, nums: List[int]):
        ans=[]
        for num in itertools.permutations(nums,len(nums)):
            ans.append(list(num))
        return(ans)
#子集:给你一个整数数组 nums ,数组中的元素互不相同,返回该数组所有可能的子集(幂集)
#解集不能包含重复的子集。你可以按任意顺序返回解集

#方法一:库函数
class Solution:
    def subsets(self, nums: List[int]):
        res = []
        for i in range(len(nums)+1):
            for tmp in itertools.combinations(nums, i):
                res.append(tmp)
        return res
#方法二:迭代
class Solution:
    def subsets(self, nums: List[int]):
        res = [[]]
        for i in nums:
            res = res + [[i] + num for num in res]
        return res
#方法三:递归(回溯算法)
class Solution:
    def subsets(self, nums: List[int]):
        res = []
        n = len(nums)
        
        def helper(i, tmp):
            res.append(tmp)
            for j in range(i, n):
                helper(j + 1,tmp + [nums[j]] )
        helper(0, [])
        return res  

二、两数之和

两数之和|

暴力枚举就不列出了,下面是哈希表

哈希表 hash 用的是 字典 dict(),哈希表查找 值为 target-nums[i] 的时间复杂度为O(1),这样的话就创建一个哈希表,对于每一个 x,我们首先查询哈希表中是否存在 target - x,然后将 x 插入到哈希表中,即可保证不会让 x 和自己匹配

class Solution:
    def twoSum(self, nums: List[int], target: int):
        hash=dict()
        k=len(nums)
        for i in range(k):
            temp=target-nums[i]
            if temp in hash:
                return [hash[temp],i]
            hash[nums[i]]=i
        

 两数之和||

用 | 的代码同样也可以过,但是这种解法同暴力枚举都是针对无序数组的,没有利用到输入数组有序的性质

方法一:上一题代码哈希表,效率还比较高

方法二:二分查找:上一题查找 target-nums[i] ,效率高是因为哈希表,而这里数组元素有序,容易想到二分查找,一个想法是一个数固定,另一个数利用二分,总不能都二分吧,那样还不如暴力枚举

class Solution:
    def twoSum(self, numbers: List[int], target: int):
        n=len(numbers)
        for i in range(n):
            left,right=i+1,n-1 #从左边一个数 i 的右边开始二分查找
            while left<=right:
                mid=(left+right)//2
                if numbers[mid]==target-numbers[i]: #找到就返回
                    return [i+1,mid+1]
                elif numbers[mid]>target-numbers[i]:
                    right=mid-1
                else:
                    left=mid+1

方法三:双指针

寻找两个和为 target 的数组元素的下标,从两边开始,i=0,j=len(numbers)-1

numbers[0]+numbers[len(numbers)-1] 要么大于目标值,要么小于目标值,要么等于(等于不就可以返回了吗),如果大于,由于数组有序,就让 j--,为什么,首先不能 i++,这样只会让和更大,那么只能 j--,同样的若某一时刻和小于目标值,就让 i++,让和变大一点,之后相等就返回

class Solution:
    def twoSum(self, numbers: List[int], target: int):
        left,right=0,len(numbers)-1
        while left<right:
            temp=numbers[left]+numbers[right]
            if temp==target:
                return [left+1,right+1]
            elif temp>target:
                right-=1
            else:
                left+=1

盛最多水的容器

第二题用到双指针,这题同样,给出代码,思路同上

class Solution:
    def maxArea(self, height: List[int]):
        i,j=0,len(height)-1
        ans=0
        while i<j:
            if height[i]<height[j]:
                ans=max(ans,height[i]*(j-i))
                i+=1
            else:
                ans=max(ans,height[j]*(j-i))
                j-=1
        return(ans)

接雨水

这题也用到双指针,动态规划是另一解法

不过显然动态规划解法容易理解

class Solution:
    def trap(self, height: List[int]):
        n=len(height)
        ans=0
        if not height:
            return(0)
        left_max=[height[0]]+[0]*(n-1)
        right_max=[0]*(n-1)+[height[n-1]]
        #两次扫描寻找第i个柱子的左边最大值和右边最大值
        for i in range(1,n):   
            left_max[i]=max(height[i],left_max[i-1])
        for i in range(n-2,-1,-1):
            right_max[i]=max(height[i],right_max[i+1])
        #很显然最左边和最右边是必定接不到雨水的
        ans=sum((min(left_max[j],right_max[j])-height[j]) for j in range(n))
        return(ans)
class Solution:
    def trap(self, height: List[int]):
        left,right=0,len(height)-1
        ans=0
        left_max=right_max=0
        while left<=right:
            if left_max<right_max:
                ans+=max(0,left_max-height[left])
                left_max=max(left_max,height[left])
                left+=1
            else:
                ans+=max(0,right_max-height[right])
                right_max=max(right_max,height[right])
                right-=1
        return(ans)

三、贪心算法

情侣牵手

class Solution:
    def minSwapsCouples(self, row: List[int]):
        result=0
        for i in range(0,len(row),2):  循环每次走两个,使得0、1,2、3....都是情侣坐在一起
            if row[i] == row[i+1] ^ 1: 
            #异或运算 ^ ,与 1 异或总能找到情侣的另一半,如 5^1=4,这是位运算,每一位相异为1
                continue
            for j in range(i+2,len(row),1):  #寻找情侣A的另一半B,与当前A的右边“同座”交换
                if row[j] == row[i] ^ 1:
                    row[i+1],row[j]=row[j],row[i+1]
                    result+=1
        return(result)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值