IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 26.<tag-数组和模拟>-lt- 31.下一个排列 + lt- 556. 下一个更大元素 III -> 正文阅读

[数据结构与算法]26.<tag-数组和模拟>-lt- 31.下一个排列 + lt- 556. 下一个更大元素 III

lt- 31.下一个排列

[案例需求]
在这里插入图片描述

[思路分析]

  • 本题解法相当朴素, 没有辣么多花里胡哨的东西;
  • 题目要求我们求出一个比当前序列稍微大一点的数, 如果本序列是递减的序列, 那已经是这个序列能够组合出来的最大数了, 题目要求我们把这个序列重排为字典序最小的序列, 直接对整个序列翻转即可;
  • 那么对于存在下一个排列的情况, 应该如何求呢?
  • 题目的关键点就在于找到一个非递减顺序的关键点, 比如3421的下一个较大的排列就是在3处找到的, 3在这个序列中非递减的,

所以整体的解题思路就是:

  1. 先倒序遍历数组, 找到第一个 (前一个数比后一个数小的位置) (即nums[i] < nums[i+1]);

  2. 这个时候我们不能直接把后一个数nums[i+1] 跟前一个数nums[i]交换就完事了; 还应该从nums[i+1]–>数组末尾这一段的数据中 找出最优的那个值( 如何最优? 即比nums[i]稍微大那么一丢丢的数, 也就是 nums[i+1]–>数组末尾中, 比nums[i]大的数中最小的那个值)

  3. 找到之后, 跟num[i]交换, 这还不算是下一个排列, num[i]后面的数值还不够小, 所以还应当进升序排列

举个栗子:

nums = [1,2,7,4,3,1],

  1. 倒序遍历数组, 找出第一组: 前一个数比后一个数小的两个数, 即[2, 7]

  2. 所处的这个位置就是需要找出比它稍微大的数的位置;

  3. 我们从[7,4,3,1]中找出比2大的数中的最小值, 也就是3, 找到后跟2交换即可;; 当然了, 如果没找到的话, 直接跳到第5步, 直接升序排列输出.

  4. 目前nums=[1,3,7,4,2,1], 不用我说你们也看出来还不算下一个排列

  5. 对3后面的数, 升序排列, 即最终结果: nums = [1,3,1,2,4,7]

[代码实现一, 学弱解法, 需要优化]

// 1. 削弱解法

class Solution {
public void nextPermutation(int[] nums) {

    int len = nums.length;

    //倒序遍历. 找出升序的第一个数
    int firstMin = -1;
    for(int i = len - 2; i >= 0; i--){
        if(nums[i] < nums[i + 1]){
            firstMin = i;
            break;
        }
    }

     if(firstMin == -1){
        reverse(nums, 0, len - 1);
         return;
    }

    System.out.println("" + firstMin);
    //在i + 1 ~ len范围内, 找出大于nums[i]的最小数
    int firstMinNum = nums[firstMin];
    int minMax = Integer.MAX_VALUE;
    int targetIndex = 0;
    for(int i = firstMin + 1; i < len; i++){
        if(nums[i] > firstMinNum){
            minMax = Math.min(minMax, nums[i]);
            if(minMax == nums[i]){
                targetIndex = i;
            }
        }
    }

   

    //交换
    swap(nums, targetIndex, firstMin);
    System.out.println("" + firstMin );
    //然后对firstMin后面的序列进行局部排序(升序排咧)
    //直接反转
    reverse(nums, firstMin + 1, len - 1);
    
    
}


public void swap(int[] nums,int left, int right){
    int temp = nums[left];
    nums[left] = nums[right];
    nums[right] = temp;
}

public void reverse(int[] nums, int begin, int end){
    while(begin < end){
        swap(nums, begin++, end--);
    }
}
}

在这里插入图片描述

[代码实现2, ]

class Solution {
    public void nextPermutation(int[] nums) {
        int i = nums.length - 2;
        // 倒序遍历, 找出第一个升序的数, 
        while (i >= 0 && nums[i] >= nums[i + 1]) {
            i--;
        }
        //经过上面的遍历, 如1,2,7,4,3,1  i此时为1 即 nums[i] = nums[1] = 2
        if (i >= 0) {
            int j = nums.length - 1;
            while (j >= 0 && nums[i] >= nums[j]) {
                j--; //找到 i后面的序列中比nums[i]大的第一个数
            }
            swap(nums, i, j);
        }
        reverse(nums, i + 1);
    }

    public void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

    public void reverse(int[] nums, int start) {
        int left = start, right = nums.length - 1;
        while (left < right) {
            swap(nums, left, right);
            left++;
            right--;
        }
    }
}

lt- 556. 下一个更大元素 III

[案例需求]
在这里插入图片描述

[思路分析]

  • 就是上一题的翻版
  • 这里只不过是要掌握以下知识点:
    1. 数字->String->char[] 三者的互相转换
    2. 数字->String: String.valueOf(number) 或 new String(number);
    3. String -> char[] : str.toCharArray()
    4. char[] --> String: new String(char数组) 或 String.valueOf(char数组)
    5. String --> 数字: Integer.parseInt(str)
    6. char --> 数字: ch - ‘0’

注意由于char字符可以用来表示acsii值, 所以也可以直接当做数字比较大小
[代码实现]

//1. 学弱解法
class Solution {
    public int nextGreaterElement(int n) {
        /**
            倒序遍历, 找到非递减的第一个数 i
            再次倒序i到末尾的序列, 找到第一个比他大的数
            交换
         */

         String numStr = String.valueOf(n);
         char[] numChars = numStr.toCharArray();

         int i = numChars.length - 2;

         while(i >= 0 && numChars[i + 1] <= numChars[i]){
             --i;
         }

         if(i < 0)return -1;
     
         
         if(i >= 0){
             int j = numChars.length - 1;
             while(j >= 0 && numChars[i] >= numChars[j]){
                 --j;
             }
    
             swap(numChars, i, j);
         }
         if(i >= 0)reverse(numChars, i + 1);

         //return i < 0 ? -1 : Integer.parseInt(new String(numChars));\
         long res = 0;

         for(char c : numChars){
             res = res * 10 + c - '0';
         }
         return res > Integer.MAX_VALUE ? -1 : (int)res;
    }


    public void swap(char[] nums, int left, int right){
        char temp = nums[left];
        nums[left] = nums[right];
        nums[right] = temp;
    }

    public void reverse(char[] nums, int j){
        int end = nums.length - 1;
        while(j < end){
            swap(nums, j++, end--);
        }
    }
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-22 19:01:27  更:2022-04-22 19:06:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:29:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码