力扣(LeetCode)31. 下一个排列(C语言)

发布于:2022-10-21 ⋅ 阅读:(267) ⋅ 点赞:(0)

一、环境说明

  1. 本文是 LeetCode 31题 : 下一个排列,使用c语言实现。
  2. 重在排列性质。
  3. 测试环境:Visual Studio 2019。

二、代码展示

//找下一个排列!
void swap(int *a,int *b){//交换
    int temp = *a;
    *a = *b;
    *b = temp;
}
void reverse(int nums[],int left,int right){//反转
    while(left<right){
        swap(nums+left,nums+right);
        left++,right--;
    }
}
void nextPermutation(int* nums, int numsSize){
    int i = numsSize - 2;
    while(i>-1&&nums[i]>=nums[i+1]){//i在nums内,nums[i]>=nums[i+1]
        i--;从右往左遍历
    }
    //此时nums[i]是第一个小于nums[i+1]的数
    int j = numsSize -1;
    if(i>-1){//如果nums已经降序排列,i是-1,走不到这一步。
        while(j>-1&&nums[i]>=nums[j]){//不考虑重复元素。//看上一行,不会越界的。
            j--;
        }
        //此时nums[j]是第一个大于nums[i]的数。
        swap(nums+i,nums+j);
    }
    reverse(nums,i+1,numsSize-1);//反转nums[i]右边的所有数
}

三、思路分析

  • 下一个排列,字典序更大。如果组成整数,下一个排列,是第一个数值大于当前排列的排列。
  • 所以我们的目的具现为:找到第一个数值大于当前排列的排列。
  • 为了找到上述排列。我们需要:
  1. 从右往左遍历,当前位置是 i i i
  2. n u m s [ i ] < n u m s [ i + 1 ] nums[i]<nums[i+1] nums[i]<nums[i+1],选定 n u m s + i nums+i nums+i作为需要被交换的数。
  3. 再次从右往左遍历 n u m s nums nums,当前位置是 j j j,当 n u m s [ j ] > n u m s [ i ] nums[j]>nums[i] nums[j]>nums[i],选取 n u m s + j nums+j nums+j作为被交换的第二个数。
  4. 此时 n u m s [ i ] nums[i] nums[i]右边肯定是降序,反转 n u m s [ i ] nums[i] nums[i]右边所有数字。
  • 按照上面操作,即可保证 n u m s nums nums的当前排列是下一个排列。

四、代码分析

  • 理解思路很重要!
  • 欢迎读者在评论区留言,作为日更博主,看到就会回复的。

五、AC

AC

六、复杂度分析

  1. 时间复杂度: O ( n ) O(n) O(n) , n n n n u m s nums nums的大小,二次遍历 n u m s nums nums的时间复杂度是 O ( n ) O(n) O(n)
  2. 空间复杂度: O ( 1 ) O(1) O(1),除若干变量使用的常量空间,没有额外使用线性空间。
本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到