一、复习
16、 最接近的三数之和
其实和双指针的三数之和差不多,就记录一个min_distract就可以了。但需要注意的是这个距离需要取绝对值。
18、 四数之和
两组双指针就搞定了哈哈
二、31. 下一个排列
1、看不懂题,问题来了:什么是字典顺序?好像也没有合适的答案。先看看高赞如何解释这道题。
2、哦是把数组里的数组成一个数字,从小到大排列。并没有什么思路。
3、自己想到了,将后面的大数和前面的小树交换。
但没想到的是:
(1)将后面尽可能小的大数与前面的数交换
(2)交换后,要对后面的几位进行升序排序来保证后面几位也是最小的【因为交换过后,就无法保证后面是升序状态】
4、写了一下,不太对,应该是部分排序没生效。就是这句nums[index[0]+1:n].sort()。看下别人怎么处理的。
class Solution:
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
n = len(nums)
res = float("inf")
for i in range(n-2,-1,-1):
for j in range(i,n):
if nums[j]>nums[i]:
res = min(nums[j]-nums[i],res)
if res ==nums[j]-nums[i]:
index = [i,j]
if res!=float('inf'):
nums[index[1]],nums[index[0]]=nums[index[0]],nums[index[1]]
return nums[index[0]+1:n].sort()
return nums.sort()
5、找了半天,没看到有sort()部分排序的借口,就自己写了个快排,还写错了一开始,直呼好家伙啊。那么多次,终于成功了。
```bash
class Solution:
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
n = len(nums)
res = float("inf")
for i in range(n-2,-1,-1):
for j in range(i,n):
if nums[j]>nums[i]:
res = min(nums[j]-nums[i],res)
if res ==nums[j]-nums[i]:
index = [i,j]
if res!=float('inf'):
nums[index[1]],nums[index[0]]=nums[index[0]],nums[index[1]]
#部分排序-冒泡
for s in range(index[0]+1,n-1):
for v in range(n-1,s,-1):
if nums[v]<nums[v-1]:
nums[v],nums[v-1]=nums[v-1],nums[v]
return nums
return nums.sort()
``
本来以为性能不佳,没想到还挺快的
6、总结一下
1、思路:
(1)换哪个左边的值:变换能变换的最右面的位,因为这样对数值改变的最小。
(2)什么时候能换:右侧值比左边大就能换。
(3)换哪个右面的值:与左边值差距最小的(已经固定了要换哪位,那当然是变大越小越符合要求啊)
(4)【!!!别忘了!!!】虽然换了值,但也不代表这就是最接近的,还要对后面几位排序。【事实就是这样的,但是如何能想到这一点,我属实不太清楚了。唯一知道的就是你换万值以后并不能保证右面的值是从小到大的,也就是最小的在最左边,造成一个右侧最小值——因为你把一个大的数换到了左边,把一个小的数换到了右边,而这个小的数并不能保证自己在所有的右边的数中是大的】
2、快排写之前要理清思路啊,画画图。正所谓,基础不牢,地动山摇。调bug太费时间了!!!总之,加油啊!
还有一题!!!哈哈哈哈哈哈哈哈哈!!!先吃个早饭!!!
33. 搜索旋转排序数组
1、我觉得二分法可以一试,那就试一试!aaa思路太不清晰了!
2、有人用二分,但是我没看懂。但也有人说先找最值。但是什么最值方法能够满足这个时间复杂度呢?
先二分查找最大值,再操作
3、简直写的绝望
class Solution:
def search(self, nums: List[int], target: int) -> int:
n = len(nums)
p=0
q=n-1
while(p<q):
mid = (p+q)//2
if nums[mid]>nums[p]:
p=mid
else:
q=mid
if target>nums[0] and target<nums[p]:
i=0
j=p
while(i<j):
mid = (i+j)//2
if nums[target]<nums[mid]:
j=mid
elif nums[target]>nums[mid]:
i=mid
else:
return mid
return -1
elif target<nums[n-1] and target >nums[p+1]:
i=p+1
j=n-1
while(i<j):
mid = (i+j)//2
if nums[target]<nums[mid]:
j=mid
elif nums[target]>nums[mid]:
i=mid
else:
return mid
return -1
else:
return -1
`
4、我想吐了,超时了。感觉二分法就是一种遍历数组的方法,只不过走的是高速通道,但最终还是遍历。这道题和传统二分法相比并不是一直都是单调的,而是曲了拐弯的,所以在写循环中造成了一定难度,但是!二分还是遍历,就生遍历,把所有的情况都看一下,如果没有符合的,就返回-1。【感觉理解的还是不够透彻,下午或者明天再看看】
class Solution:
def search(self, nums: List[int], target: int) -> int:
n = len(nums)
if n==1:
if nums[0]==target:
return 0
else:
return -1
p=0
q=n-1
while(p<q):
mid = (p+q)//2
if nums[mid]>nums[p]:
p=mid
else:
q=mid
if target==nums[0]:
return 0
if target==nums[p]:
return p
if target==nums[p+1]:
return p+1
if target==nums[n-1]:
return n-1
if target>nums[0] and target<nums[p]:
i=0
j=p
while(i<j):
mid = (i+j)//2
if nums[target]<nums[mid]:
j=mid
elif nums[target]>nums[mid]:
i=mid
else:
return mid
return -1
elif target<nums[n-1] and target >nums[p+1]:
i=p+1
j=n-1
while(i<j):
mid = (i+j)//2
if nums[target]<nums[mid]:
j=mid
elif nums[target]>nums[mid]:
i=mid
else:
return mid
return -1
else:
return -1
5、直接看标答了,真的想吐了。
class Solution:
def search(self, nums: List[int], target: int) -> int:
if not nums:
return -1
l, r = 0, len(nums) - 1
while l <= r:
mid = (l + r) // 2
if nums[mid] == target:
return mid
if nums[0] <= nums[mid]:
if nums[0] <= target < nums[mid]:
r = mid - 1
else:
l = mid + 1
else:
if nums[mid] < target <= nums[len(nums) - 1]:
l = mid + 1
else:
r = mid - 1
return -1
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array/solution/sou-suo-xuan-zhuan-pai-xu-shu-zu-by-leetcode-solut/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。