二分#背包#快排#LCS详解
文章目录
- 二分#背包#快排#LCS详解
- 1. 二分搜索
- 2. 01背包问题
- 3. 快速排序
- 4. 最长公共子序列
1. 二分搜索
在处理大规模数据集时,查找操作的效率显得尤为重要。二分搜索是一种在有序数组中查找目标值的高效算法,其时间复杂度为O(log n)。
二分搜索通过每次比较目标值与数组中间元素的大小来缩小搜索范围。每次比较后,搜索范围缩小一半,直到找到目标值或搜索范围为空。
二分搜索适用于以下场景:
- 快速查找有序数组中的目标值。
- 数据库系统中常用二分搜索在B树或B+树索引中查找记录。
- 需要在算法中频繁查找数据的场景,如在排序数据中查找特定元素。
力扣 LCR 068. 搜索插入位置
给定一个排序的整数数组 nums 和一个整数目标值 target ,请在数组中找到 target ,并返回其下标。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
示例 1:
输入: nums = [1,3,5,6], target = 5
输出: 2
示例 2:
输入: nums = [1,3,5,6], target = 2
输出: 1
示例 3:
输入: nums = [1,3,5,6], target = 7
输出: 4
示例 4:
输入: nums = [1,3,5,6], target = 0
输出: 0
示例 5:
输入: nums = [1], target = 0
输出: 0
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 为无重复元素的升序排列数组
-104 <= target <= 104
案例代码
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
l,r=0,len(nums)-1
while l<=r:
mid=(l+r)//2
if nums[mid]==target:
return mid
elif nums[mid]>target:
r=mid-1
else :
l=mid+1
return l
2. 01背包问题
C/C++详解地址:01背包和完全背包
背包问题是一类经典的优化问题,涉及在给定容量的背包中选择物品以使得背包内物品的总价值最大化。
0/1背包问题通过动态规划解决,使用一个二维数组 dp
来记录每个子问题的解。dp[i][w]
表示前 i
个物品在背包容量为 w
时的最大价值。
背包问题适用于以下场景:
- 在有限资源下,如何选择最优方案以获得最大收益。
- 在有限资金下选择投资组合以最大化收益。
- 在有限预算下选择项目组合以最大化回报。
例题:
动态规划:
dp[i][j] = max(dp[i-1][j], dp[i-1][j-wi] + vi)
Python代码实现
n,v=map(int,input().split())
dp=[[0]*(v+1) for i in range(n+1)] # [[0]*cols for i in range(rows)]
for i in range(1,n+1):
wi,vi=map(int,input().split())
for j in range(0,v+1):
if j>=wi:
dp[i][j]=max(dp[i-1][j],dp[i-1][j-wi]+vi)
else:
dp[i][j]=dp[i-1][j]
print(dp[n][v])
3. 快速排序
快速排序是一种高效的排序算法,其平均时间复杂度为O(n log n)。快速排序通过分治法将数组分成两部分,递归地排序每部分。
快速排序通过选择一个基准元素(pivot),将数组分为两部分,一部分小于基准元素,另一部分大于基准元素。然后递归地对这两部分进行排序。
快速排序适用于以下场景:
- 处理大规模数据集的排序任务。
- 大多数编程语言的内置排序函数都采用了快速排序或其变种。
- 在数据分析和处理过程中,对数据进行排序以便后续操作。
力扣 4. 排序数组
给你一个整数数组 nums,请你将该数组升序排列。
示例 1:
输入:nums = [5,2,3,1]
输出:[1,2,3,5]
示例 2:
输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]
提示:
1 <= nums.length <= 5 * 104
-5 * 104 <= nums[i] <= 5 * 104
python代码示例
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
def partition(arr, low, high):
pivot = arr[low]
left, right = low, high
while left < right:
while left<right and arr[right] >= pivot:
right -= 1
arr[left] = arr[right]
while left<right and arr[left] <= pivot:
left += 1
arr[right] = arr[left]
arr[left] = pivot
return left
def randomPartition(arr, low, high):
pivot_idx = random.randint(low, high)
arr[low], arr[pivot_idx] = arr[pivot_idx], arr[low]
return partition(arr, low, high)
def quickSort(arr, low, high):
if low >= high:
return
mid = randomPartition(arr, low, high)
quickSort(arr, low, mid-1)
quickSort(arr, mid+1, high)
quickSort(nums, 0, len(nums)-1)
return nums
4. 最长公共子序列
C/C++详解地址:LCS、LIS模型详解
最长公共子序列(LCS)是指在两个序列中,找出长度最长的公共子序列。
LCS通过动态规划解决,使用一个二维数组 dp
来记录每个子问题的解。dp[i][j]
表示 text1[0..i-1]
和 text2[0..j-1]
的LCS长度。
LCS适用于以下场景:
- 文本比较:在文本处理和比较中,用于查找两个文本的相似度。
- 版本控制:在版本控制系统中,用于计算两个版本之间的差异。
- 生物信息学:在基因序列分析中,用于查找DNA序列的相似部分。
python代码示例
def LCS(a, b):
n = len(a)
m = len(b)
dp = [[0] * (m + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
for j in range(1, m + 1):
if a[i - 1] == b[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
else:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
return dp[n][m]
n,m=map(int,input().split())
a=list(map(int,input().split()))
b=list(map(int,input().split()))
result = LCS(a, b)
print(result)
如果对Golang、Mysql、Linux感兴趣的小伙伴,也可以关注我的公众号0.o