Leetcode-D38-数组-31. 下一个排列&33. 搜索旋转排序数组

一、复习

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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值