力扣热题100道之31下一个排列

解法

题解中的思路自己写的代码

大体思路跟我的差不多,区别的地方在于题解的实现算法的能力更好一些。比如找到index右边的最小的大数。可以直接从右边向左边遍历,而我的做法是从左边向右边遍历,这就导致做法非常的麻烦,要判断的东西很多。

复制代码
class Solution {
    public void nextPermutation(int[] nums) {
        int n=nums.length;
        int index=n-1;
        while(index>0&&nums[index]<=nums[index-1]){
            index--;
        }
        if(index==0){
            sort(nums,0);
        }else{
            for(int j=n-1;j>=index;j--){
                if(nums[j]>nums[index-1]){
                    swap(nums,index-1,j);
                    sort(nums,index);
                    break;
                }
                
            }
        }
        
    }
    public void sort(int []nums,int i){
        for(int k=i;k<nums.length;k++){
            int min=k;
            for(int s=k;s<nums.length;s++){
                if(nums[min]>nums[s])min=s;
            }
            swap(nums,min,k);
        }
    }
    public void swap(int []nums,int i,int j){
        int tmp=nums[i];
        nums[i]=nums[j];
        nums[j]=tmp;
    }
}
自己的解法

思路

从右向左遍历数组,找到第一个数字记作index,这个数字比前一位数字要大,然后判断

如果index=0,也就是数组是递减的,那么直接将整个数组从小到大排个序就好了。

在index向右遍历,找到index右边的比index-1大的最小的数字记作min,判断

如果右边没有比index更大的数字那么交换index和index-1,将从index到最后的数字从小到大排序

如果找到了min,交换index-1和min,将index到最后的数字从小到大排序。

算法流程描述

  1. 寻找转折点

    从右向左遍历数组,定位第一个满足 nums[index] > nums[index-1]的位置 index,该位置标志着字典序增长的潜在转折点。

  2. 处理完全降序情况

    index = 0,表明整个数组呈完全降序排列,此时直接将数组整体按升序排序即可得到最小排列。

  3. 寻找最小交换元素

    index右侧区间内,寻找比 nums[index-1]大的最小元素,记为 minValue(或其位置 minIndex)。

  4. 执行元素交换

    • 情况一 :若右侧不存在比 nums[index-1]更大的元素,则交换 nums[index]nums[index-1]

    • 情况二 :若找到 minValue,则交换 nums[index-1]minValue

  5. 优化剩余序列

    index至数组末尾的子序列按升序排序,确保该区间构成最小字典序,从而得到严格的下一个排列。

这道题目中学到的

在这道题目中我很迷糊,在如何找到index右边的比index-1大的最小的数字上花了很长时间。最后我发现,直接在主方法的外面单独创建一个方法来专门解决这个问题,会好很多。

复制代码
class Solution {
    public void nextPermutation(int[] nums) {
        int n=nums.length;
        int index=n-1;
        int poi=n-1;
        while(index>0&&nums[index]<=nums[index-1]){
            if(index!=n-1)poi--;
            index--;
        }
        if(index==0){
            sort(nums,0,n-1);
        }else{
            int mini=findMin(nums,index+1,nums[index-1]);
            if(mini==-1){
                swap(nums,index,index-1);
                sort(nums,index,n-1);
            }else{
                swap(nums,mini,index-1);
                sort(nums,index,n-1);
            }
        }
        
    }
    public void sort(int []nums,int i,int j){
        for(int k=i;k<=j;k++){
            int min=k;
            for(int s=k;s<=j;s++){
                if(nums[min]>nums[s])min=s;
            }
            swap(nums,min,k);
        }
    }
    public void swap(int []nums,int i,int j){
        int tmp=nums[i];
        nums[i]=nums[j];
        nums[j]=tmp;
    }
    public int findMin(int []nums,int i,int num){
        int mini=i;
        int n=nums.length;
        if(i>n-1)return -1;
        for(int k=i;k<nums.length;k++){
            if(nums[k]<=num){
                mini=k;
                break;
            }
        }
        if(mini==i&&nums[mini]<=num){
            return -1;
        }else if(mini==i&&nums[mini]>num){
            return n-1;
        }else{
            return mini-1;
        }
       
    }
}
相关推荐
米尔的可达鸭1 小时前
深入操作系统 Socket 底层:套接字控制块、FD映射、阻塞IO核心完整实现
arm开发·数据结构·websocket·网络协议·算法·架构·安全架构
tachibana21 小时前
hot100 课程表(207)
java·数据结构·算法·leetcode
神仙别闹1 小时前
编写基于C++ Huffman 算法的无损压缩程序和解压程序
java·c++·算法
大鱼>1 小时前
宠物活动轨迹追踪系统:GPS/BDS+UWB+BLE多定位融合方案
人工智能·深度学习·算法·iot·宠物
旖-旎2 小时前
《LeetCode 646 最长数对链 || LeetCode 1143 最长公共子序列》
c++·算法·leetcode·动态规划
Frostnova丶2 小时前
(15)LeetCode 189. 轮转数组
数据结构·算法·leetcode
Lumos1862 小时前
故障保护与鲁棒性(十七)
算法
手写码匠3 小时前
从零实现大模型推理引擎:Continuous Batching 与动态调度系统深度解析
人工智能·深度学习·算法·aigc
wabs6663 小时前
关于单调栈【力扣503.下一个更大元素II的思考】
算法·单调栈
c238563 小时前
下篇:伸缩魔法!进阶吃透可变滑动窗口篇
c++·算法