文章目录
一,俄罗斯套娃信封问题
1,程序简介
给你一个二维整数数组 envelopes ,其中 envelopes[i] = [wi, hi] ,表示第 i 个信封的宽度和高度。
当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。
请计算 最多能有多少个 信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。
注意:
- 不允许旋转信封。
示例 1:
- 输入:envelopes = [[5,4],[6,4],[6,7],[2,3]]
- 输出:3
- 解释:最多信封的个数为
3, 组合为:
[2,3] => [5,4] => [6,7]。
示例 2:
- 输入:envelopes = [[1,1],[1,1],[1,1]]
- 输出:1
提示:
- 1 < = e n v e l o p e s . l e n g t h < = 5000 1 <= envelopes.length <= 5000 1<=envelopes.length<=5000
- e n v e l o p e s [ i ] . l e n g t h = = 2 envelopes[i].length == 2 envelopes[i].length==2
- 1 < = w i , h i < = 1 0 4 1 <= wi, hi <= 10^4 1<=wi,hi<=104
2,程序代码
# -*- coding: utf-8 -*-
"""
Created on Sun Feb 13 21:48:03 2022
Function: 俄罗斯套娃信封问题
@author: 小梁aixj
"""
class Solution:
def maxEnvelopes(self, envelopes) -> int:
"""
:param envelopes: List[List[int]]
:return: int
"""
n = len(envelopes)
if not n:
return 0
envelopes.sort(key=lambda x: (x[0], -x[1]))
dp = [1] * n
for i in range(n):
for j in range(i):
if envelopes[j][1] < envelopes[i][1]:
dp[i] = max(dp[i], dp[j] + 1)
return max(dp)
二,直线上最多的点数
1,程序简介
给你一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。
示例 1:
- 输入:points = [[1,1],[2,2],[3,3]]
- 输出:3
示例 2:
- 输入:points = [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
- 输出:4
提示:
- 1 <= points.length <= 300
- points[i].length == 2
- − 1 0 4 < = x i , y i < = 1 0 4 -10^4 <= xi, yi <= 10^4 −104<=xi,yi<=104
- points 中的所有点 互不相同
2,程序代码
# -*- coding: utf-8 -*-
"""
Created on Sun Feb 13 21:48:24 2022
Function: 直线上最多的点数
@author: 小梁aixj
"""
class Solution:
def maxPoints(self, points: List[List[int]]) -> int:
if len(points) <= 2:
return len(points)
maxNum = 0
for i in range(len(points)):
maxNum = max(maxNum, self.find(points[i], points[:i] + points[i + 1 :]))
return maxNum + 1
def find(self, point, pointList):
memories = {}
count = 0
inf = float("inf")
for curPoint in pointList:
if curPoint[1] == point[1] and curPoint[0] != point[0]:
memories[inf] = memories.get(inf, 0) + 1
elif curPoint[1] == point[1] and curPoint[0] == point[0]:
count += 1
else:
slope = (curPoint[0] - point[0]) / (curPoint[1] - point[1])
memories[slope] = memories.get(slope, 0) + 1
if memories:
return count + max(memories.values())
else:
return count
三,寻找旋转排序数组中的最小值 II
1,程序简介
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,4,4,5,6,7] 在变化后可能得到:
- 若旋转 4 次,则可以得到 [4,5,6,7,0,1,4]
- 若旋转 7 次,则可以得到 [0,1,4,4,5,6,7]
注意,数组 [a[0], a[1], a[2], …, a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], …, a[n-2]] 。
给你一个可能存在 重复 元素值的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
示例 1:
- 输入:nums = [1,3,5]
- 输出:1
示例 2:
- 输入:nums = [2,2,2,0,1]
- 输出:0
提示:
- n == nums.length
- 1 <= n <= 5000
- -5000 <= nums[i] <= 5000
- nums 原来是一个升序排序的数组,并进行了 1 至 n 次旋转
进阶:
- 这道题是 寻找旋转排序数组中的最小值(https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/description/) 的延伸题目。
- 允许重复会影响算法的时间复杂度吗?会如何影响,为什么?
2,程序代码
# -*- coding: utf-8 -*-
"""
Created on Sun Feb 13 21:49:48 2022
Function: 寻找旋转排序数组中的最小值 II
@author: 小梁aixj
"""
class Solution:
def findMin(self, nums: List[int]) -> int:
left = 0
right = len(nums) - 1
while left < right:
mid = left + (right - left) // 2
if nums[mid] > nums[right]:
left = mid + 1
elif nums[mid] == nums[right]:
right -= 1
else:
right = mid
return nums[left]