想要精通算法和SQL的成长之路 - 下一个排列

news2024/11/24 22:28:01

想要精通算法和SQL的成长之路 - 下一个排列

  • 前言
  • 一. 下一个排列
  • 二. 下一个更大元素III

前言

想要精通算法和SQL的成长之路 - 系列导航

一. 下一个排列

原题链接

整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。

例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1]
整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。

例如,arr = [1,2,3] 的下一个排列是 [1,3,2] 。类似地,arr = [2,3,1] 的下一个排列是 [3,1,2] 。而 arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。给你一个整数数组 nums ,找出 nums 的下一个排列。

必须 原地 修改,只允许使用额外常数空间。

示例 1:

  • 输入:nums = [1,2,3]
  • 输出:[1,3,2]

我们来分析一下题干:

  1. 首先我们需要找到排列组合当中,下一个更大的值。
  2. 如果不存在,那么就输出字典排序的最小值,即升序排序。

思路:

  1. 我们希望修改后的数字比原数字大,但是它要尽可能的小, 也就是说,我们改动的区间要尽可能地在数组右侧范围。
  2. 如果某段区间范围内的数字是升序的,比如123,那么这段区间数字已经是最小。因此我们需要找一个含降序,也就是包含封顶的一个区间。例如132。
  3. 那么结合上述两点,我们以123465为例。我们可以从后往前遍历,找到第一个数字,满足 nums[i-1] < nums[i],这里就是4。
  4. 那么此时,我们以4所在位置为分界线,我们找到分界线右侧尽可能小的数字和4进行交换。也就是5。毕竟123564比123645还要小。也就是找到第一个比4大的。
  5. 交换之后,我们还无法百分百保证,替换后的数字一定是下一个更小的。怎么办呢?我们把替换后的右侧区间,进行升序排序就完事了。 和第四步不冲突。
public void nextPermutation(int[] nums) {
    // 从后往前遍历,找到第一个比后一个元素小的下标。以123465为例,那就是找到了元素4.
    for (int i = nums.length - 1; i > 0; i--) {
        if (nums[i] > nums[i - 1]) {
            // 将分界线右侧的数字进行升序排序,这样一来,右侧的数字组合必定是最小。
            Arrays.sort(nums, i, nums.length);
            // 在右侧找到第一个比i-1位置大的元素
            for (int j = i; j < nums.length; j++) {
                if (nums[j] > nums[i - 1]) {
                    // 找到了就交换他们
                    int tmp = nums[j];
                    nums[j] = nums[i - 1];
                    nums[i - 1] = tmp;
                    return;
                }
            }
        }
    }
    // 如果找不到更大的,就输出字典序升序
    Arrays.sort(nums);
}

总结就是:

  1. 从右往左找到第一个封顶。记录封顶左侧的下标为A。
  2. 将A右侧的数字区间进行升序排序
  3. 右侧区间中找到第一个比下标为A的数值大的,进行交换。

最终结果就是下一个更大值的排列。

那么我们再来看一下这一个题目的变种怪。

二. 下一个更大元素III

给你一个正整数 n ,请你找出符合条件的最小整数,其由重新排列 n 中存在的每位数字组成,并且其值大于 n 。如果不存在这样的正整数,则返回 -1 。

注意 ,返回的整数应当是一个 32 位整数 ,如果存在满足题意的答案,但不是 32 位整数 ,同样返回 -1 。

示例 1:

  • 输入:n = 12
  • 输出:21

这一题和上一题几乎一模一样,唯一的不同就是:

  • 题一:给的是数组。
  • 题二:给的是整数。

思路:

  1. 我们在“下一个排列”的基础上,只需要将整数给他转成数组即可。

代码如下:

public int nextGreaterElement(int n) {
    char[] nums = String.valueOf(n).toCharArray();
    for (int i = nums.length - 1; i > 0; i--) {
        // 找到第一个数:满足当前数比后一个数小的,我们称Nums[i-1]为分界数
        if (nums[i] > nums[i - 1]) {
            // 将分线数右侧的区间进行升序排序(字典序最小)
            Arrays.sort(nums, i, nums.length);
            // 右侧找到第一个比分界数大的
            for (int j = i; j < nums.length; j++) {
                // 找到之后 ,和分界数交换一下值
                if (nums[j] > nums[i - 1]) {
                    char tmp = nums[j];
                    nums[j] = nums[i - 1];
                    nums[i - 1] = tmp;
                    // 当然,由于题目的提示和要求,还要进行长度判断,需要一个32位整数,超过了就要返回-1
                    long res = Long.parseLong(String.valueOf(nums));
                    if (res > Integer.MAX_VALUE) {
                        return -1;
                    }
                    return (int) res;
                }
            }
        }
    }
    // 找不到更大的数,返回-1
    return -1;
}

这里有一个点需要注意一下,返回res的时候,一定要强转成int,否则会报错:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/616730.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Wi-Fi 6还没用熟,Wi-Fi 7就要来了,性能“高攀不起”!

Wi-Fi作为一种无线通信技术&#xff0c;在现代生活中扮演着重要的角色。随着无线设备数量的不断增加和对高速、高容量网络的需求日益增长&#xff0c;Wi-Fi技术不断发展演进。在过去的几十年中&#xff0c;我们见证了多个Wi-Fi技术标准的推出&#xff0c;其中最新的一代是Wi-Fi…

Spring Boot集成Redisson布隆过滤器案例

1 什么是布隆过滤器 布隆过滤器实际上是一个非常长的二进制向量(bitmap)和一系列随机哈希函数。那什么又叫哈希函数呢&#xff1f;哈希函数指将哈希表中元素的关键键值通过一定的函数关系映射为元素存储位置的函数。&#xff08;HashMap源码&#xff09; 布隆过滤器的优点&…

python基于轻量级CNN模型开发构建手写藏文数字识别系统

最近做的很多工作都是跟手写性质的数据集有关的&#xff0c;比如&#xff1a;手写汉字、手写甲骨文、手写数字、手写字母等等&#xff0c;今天主要做的实践是对藏文中的手写数字进行识别分析&#xff0c;在我之前的博文中有很多相关的实践分析&#xff0c;感兴趣的话可以自行移…

图解Redis中的9种数据结构

如图所示&#xff0c;Redis中提供了9种不同的数据操作类型&#xff0c;他们分别代表了不同的数据存储结构。 图2-17 数据类型 String类型 String类型是Redis用的较多的一个基本类型&#xff0c;也是最简单的一种类型&#xff0c;它和我们在Java中使用的字符类型什么太大区别&…

MyBatis 万字进阶

文章目录 一. 增, 删, 改 操作1.1 修改操作1.2 删除操作1.3 添加操作1.3.1 返回受影响行数1.3.2 返回 id 二. 查询操作2.1 单表查询2.1.1 参数占位符 ${} 和 #{}2.1.2 SQL 注入问题2.1.3 ${} 的优点2.1.4 Like 查询 2.2 多表查询2.2.1 返回类型 resultType2.2.2 返回字典映射 r…

Linux内核进程创建流程

本文代码基于Linux5.10 内容主要参考《Linux内核深度解析》余华兵 当Linux内核要创建一个新进程时&#xff0c; 流程大致如下 ret fork(); if (ret 0) {/* 子进程装载程序 */ret execve(filename, argv, envp); } else if (ret > 0) {/* 父进程 */ } 大致可以分为创建新…

pagehelper分页插件(SpringBoot,Mybatis整合前后端分析)

前言&#xff1a;在学习项目的过程中遇到了数据分页的功能&#xff0c;单纯的js前端不能处理大的数据量&#xff0c;需要后端整理好数据发送给前端&#xff0c;那么使用分页插件无疑是个好选择. 目录 pagehelper依赖 接口方法mapper Mybatis Service ServiceImpl PageResu…

[IJCAI 2022] 基于个性化掩码的实用安全联合推荐

Practical and Secure Federated Recommendation with Personalized Mask | SpringerLink 摘要 联合推荐解决了推荐系统的数据筒仓和隐私问题。目前的联合推荐系统主要利用密码学或混淆方法来保护原始评分不被泄露。然而&#xff0c;前者带来了额外的通信和计算成本&#xff0…

day 49 :121. 买卖股票的最佳时机;122. 买卖股票的最佳时机 II;123. 买卖股票的最佳时机 III

买卖股票 121. 买卖股票的最佳时机&#xff1a;一次买入卖出1. 贪心算法2. 动态规划1. dp数组以及下标名义2. 递归公式3. dp数组如何初始化4. 代码 122. 买卖股票的最佳时机 II:可以多次买入卖出2. 动态规划1. dp数组以及下标名义2. 递归公式3. dp数组如何初始化4. 代码 123. 买…

Linux_进程

目录 一.进程概念与子进程 1.进程基本概念 2.通过系统调用创建子进程-fork 二.进程状态 1、一般进程状态 2、Linux操作系统的进程状态 三.环境变量 1.概念 2.环境变量组织与获取 3.配置文件 4.环境变量的全局属性​编辑 5.命令行参数 四.进程优先级 1.查看系统进…

Linux文件系统-磁盘划分

一、磁盘使用 windows系统中&#xff1a; 1、分区 2、格式化 3、自动装载 4、使用 Linux系统中&#xff1a;1、分区 2、格式化 3、手动挂载 &#xff08;挂载到/etc/fstab实现开机自启&#xff09; 4、使用 Linux系统中磁盘使用&#xff1a; 1、分区操作…

rust:cargo 和rustc 以及一点 小技巧

在正式学习 Rust 语言以前&#xff0c;我们需要先学会怎样输出一段文字到命令行&#xff0c;这几乎是学习每一门语言之前必备的技能&#xff0c;因为输出到命令行几乎是语言学习阶段程序表达结果的唯一方式。 在之前的 Hello, World 程序中大概已经告诉了大家输出字符串的方式…

system V共享内存

一、前言 共享内存是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间&#xff0c;这些进程间数据传递将不再涉及到内核&#xff0c;换句话说&#xff0c;进程将不再通过执行进入系统内核的系统调用来传递彼此的数据。 但其实比它好用的进程间通信还有很多种&…

Android HTTP请求方式:HttpClient

1.HttpClient使用流程 基本流程&#xff1a; 2.HttpClient使用示例 1&#xff09;使用HttpClient发送GET请求 直接贴下简单的发送Get请求的代码&#xff1a; public class MainActivity extends Activity implements OnClickListener { private Button btnGet; private WebV…

什么是OSPF被动接口?如何配置?华为、思科、瞻博网络三厂商命令来了

OSPF&#xff08;开放最短路径优先&#xff09;是一种常用的动态路由协议&#xff0c;用于在大型网络中实现路由选择。在OSPF中&#xff0c;被动接口是一种特殊类型的接口&#xff0c;它被用来监测网络中的邻居关系&#xff0c;并接收来自邻居发送的Hello消息。被动接口不主动发…

华为OD机试之在字符串中找出连续最长的数字串(含“+-”号)(Java源码)

在字符串中找出连续最长的数字串(含“”号) 输入描述 请在一个字符串中找出连续最长的数字串&#xff0c;并返回这个数字串。 如果存在长度相同的连续数字串&#xff0c;返回最后一个。 如果没有符合条件的字符串&#xff0c;返回空字符串””。 注意&#xff1a; 数字串可以由…

Ansible进阶2——角色管理

文章目录 一、角色1.1 获取角色方式1.2 角色结构1.3 定义变量和默认变量1.4 使用方法1.5 控制playbook中的任务执行流程 二、红帽企业Linux系统角色2.1 常见系统角色2.2 使用系统时间同步角色 三、自定义角色3.1 创建角色目录结构3.2 编写角色内容3.3 编写总结 四、ansible gal…

【C++】内存管理的基本操作,new与delete的实现原理以及operator new与operator delete函数

文章目录 前言一、new,delete操作内置类型二、new/delete操纵自定义类型3. operator new与operator delete函数4. new/delete实现原理4.malloc/free和new/delete的区别 前言 程序中内存的划分&#xff1a; 栈又叫堆栈–非静态局部变量/函数参数/返回值等等&#xff0c;栈是向…

高考必胜,归来仍是少年!

高考必胜&#xff0c;归来仍是少年&#xff01; 这是小索奇专门为高考生写的文章高考生 我以前给大家弄过一些免费的付费资料&#xff0c;现在看到后台很多伙伴们都在寻找资料&#xff0c;一些没有充分准备的小伙伴此刻一定很匆忙吧&#xff01; 我想对大家说&#xff1a; 高…

基于 FFMPEG 的跨平台视频播放器简明教程(二):基础知识和解封装(demux)

系列文章目录 基于 FFMPEG 的跨平台视频播放器简明教程&#xff08;一&#xff09;&#xff1a;FFMPEG Conan 环境集成 文章目录 系列文章目录前言基础知识视频&#xff0c;你所看到的&#xff01;音频 - 你所听到的声音编解码器 - 压缩数据容器 - 存放音频和视频的地方 解封…