【力扣 Hot100】刷题日记

D8 全排列(非回溯法)

全排列原题链接

在刷leetcode的时候,看到这道题目并没法使用像STL的next_permutation方法,感叹C++便利的同时,又惋惜Java并没有类似的API,那我们只能从原理入手了,仿写此算法。

其实回溯法更应该掌握,因为扩展性高,我们学知识本来就是举一反三的,如果这个算法只适用于这道题,那我们深入学习的必要性就没那么大了。

我们来看实现过程:

1. 找到「下降点」i

  • 从右向左扫描数组,找到第一个 arr[i] < arr[i+1] 的位置 i
  • 为什么要找这个?因为字典序的排列从右向左最长的非递增序列是当前排列的尾部,我们想找到可以“升高”的那个位置。

说人话就是,这里非递增序列我们先理解为递减序列(其实还包括前后相等),其实是找递减序列的入口,为什么呢?

因为按照字典序来看,这一部分是不便于排列的,因为难以升高,我们得优先换这部分的前一部分。

如果还是不理解,可以继续往后看,看到后面就会明白这里为什么找下降点。

举例:
arr = [1, 3, 5, 4, 2]
从右往左,观察 arr[i] >= arr[i+1]

  • 4 >= 2 → 是
  • 5 >= 4 → 是
  • 3 >= 5 → 否,3 < 5
    所以 i = 1(对应数字 3)。
  • 如果 i < 0,说明整个数组是非递增序列(即当前排列是最大字典序),没有下一个排列,函数返回 false

2. 找到交换点 j

  • 从右向左找到第一个 arr[j] > arr[i] 的位置。
  • arr[i] 后面的序列中找一个比 arr[i] 大的最小数字交换,使排列字典序刚好变大一点。

继续上例:
i=1arr[i]=3
从右往左找第一个比 3 大的元素:

  • 2 <= 3 不符合
  • 4 > 3 符合,且是最右边的符合条件元素
    所以 j = 3

3. 交换 arr[i]arr[j]

交换 34,变成:

[1, 4, 5, 3, 2]

4. 反转 i+1 位置到数组末尾的部分

i+1 到末尾的子数组反转(升序排列),保证新排列是字典序中「紧接着」的下一排列。

这里 i+1=2,子数组是 [5, 3, 2],反转后是 [2, 3, 5],数组变成:

[1, 4, 2, 3, 5]

这个就是字典序的下一个排列。

既然这样,那么我们需要实现两个函数swapreverse

class Solution {public List<List<Integer>> permute(int[] nums) {Arrays.sort(nums); //这段代码用于判断List<List<Integer>> ans = new ArrayList<>();do{List<Integer> temp = new ArrayList<>();for (int num : nums) {temp.add(num);}ans.add(temp);}while(nextPermutation(nums));return ans;}private static boolean nextPermutation(int[] arr){int i = arr.length - 2;while(i >= 0 && arr[i] >= arr[i + 1]) i--; //找到下降点if(i < 0) return false;int j = arr.length - 1;while(arr[j] <= arr[i]) j--; //找出比下降点大的swap(arr, i, j);reverse(arr, i + 1, arr.length - 1);return true;}private static void swap(int[] arr, int i, int j){int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}private static void reverse(int arr[], int l, int r){while(l < r) swap(arr, l++, r--);}
}

如果这篇文章对你有帮助,请点赞评论收藏,创作不易,你的支持是我坚持的动力。

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

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

相关文章

JetPack系列教程(七):Palette——让你的APP色彩“飞”起来!

JetPack系列教程&#xff08;七&#xff09;&#xff1a;Palette——让你的APP色彩“飞”起来&#xff01; 各位开发小伙伴们&#xff0c;还在为APP的配色发愁吗&#xff1f;别担心&#xff0c;今天咱们就来聊聊JetPack家族里的“色彩魔法师”——Palette&#xff01;这个神奇的…

力扣hot100 | 矩阵 | 73. 矩阵置零、54. 螺旋矩阵、48. 旋转图像、240. 搜索二维矩阵 II

73. 矩阵置零 力扣题目链接 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]]…

ARC与eARC是什么?主要用在哪?

在家庭影音设备不断升级的今天&#xff0c;人们对音视频体验的要求越来越高。无论是追剧、玩游戏还是观看电影大片&#xff0c;很多用户不再满足于电视自带的扬声器&#xff0c;而是希望借助回音壁、功放或家庭影院系统&#xff0c;获得更加震撼的沉浸式声音体验。一、ARC是什么…

解锁JavaScript性能优化:从理论到实战

文章目录 前言 一、常见性能瓶颈剖析 二、实战案例与优化方案 (一)DOM 操作优化案例​ (二)事件绑定优化案例​ (三)循环与递归优化案例​ (四)内存管理优化案例​ 三、性能优化工具介绍 总结 前言 性能优化的重要性 在当今数字化时代,Web 应用已成为人们生活和工作…

结构化记忆、知识图谱与动态遗忘机制在医疗AI中的应用探析(上)

往期相关内容推荐: 基于Python的多元医疗知识图谱构建与应用研究(上)

XSS攻击:从原理入门到实战精通详解

一、XSS攻击基础概念1.1 什么是XSS攻击 XSS&#xff08;Cross-Site Scripting&#xff0c;跨站脚本攻击&#xff09;是一种将恶意脚本注入到可信网站中的攻击手段。当用户访问被注入恶意代码的页面时&#xff0c;浏览器会执行这些代码&#xff0c;导致&#xff1a;用户会话被劫…

Leetcode 14 java

今天复习一下以前做过的题目&#xff0c;感觉是忘光了。 160. 相交链表 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数…

用 FreeMarker 动态构造 SQL 实现数据透视分析

在 ERP、BI 等系统中&#xff0c;数据透视分析&#xff08;Pivot Analysis&#xff09;是非常常见的需求&#xff1a;用户希望按任意维度&#xff08;如门店、时间、商品分类等&#xff09;进行分组统计&#xff0c;同时选择不同的指标&#xff08;如 GMV、订单数、客单价等&am…

13.深度学习——Minst手写数字识别

第一部分——起手式 import torch from torchvision import datasets, transforms import torch.nn as nn import torch.nn.functional as F import torch.optim as optimuse_cuda torch.cuda.is_available()if use_cuda:device torch.device("cuda") else: device…

【JAVA高级】实现word转pdf 实现,源码概述。深坑总结

之前的需求做好后,需求,客户突发奇想。要将生成的word转为pdf! 因为不想让下载文档的人改动文档。 【JAVA】实现word添加标签实现系统自动填入字段-CSDN博客 事实上这个需求难度较高,并不是直接转换就行的 word文档当中的很多东西都需要处理 public static byte[] gener…

数据驱动测试提升自动化效率

测试工程师老王盯着满屏重复代码叹气&#xff1a;“改个搜索条件要重写20个脚本&#xff0c;这班加到啥时候是个头&#xff1f;” 隔壁组的小李探过头&#xff1a;“试试数据驱动呗&#xff0c;一套脚本吃遍所有数据&#xff0c;我们组上周测了300个组合都没加班&#xff01;”…

模板引用(Template Refs)全解析2

三、v-for 中的模板引用 当在 v-for 中使用模板引用时,引用的 value 会自动变为一个数组,包含列表中所有元素/组件的引用(需 Vue 3.5+ 版本,旧版需手动处理且顺序不保证)。 1. 基本用法(Vue 3.5+) <script setup> import { ref, useTemplateRef, onMounted } f…

【Linux系统】进程间通信:System V IPC——共享内存

前文中我们介绍了管道——匿名管道和命名管道来实现进程间通信&#xff0c;在介绍怎么进行通信时&#xff0c;我们有提到过不止管道的方式进行通信&#xff0c;还有System V IPC&#xff0c;今天这篇文章我们就来学习一下System V IPC中的共享内存1. 为何引入共享内存&#xff…

[优选算法专题二滑动窗口——最大连续1的个数 III]

题目链接 最大连续1的个数 III 题目描述 题目解析 问题本质 输入&#xff1a;二进制数组nums&#xff08;只包含 0 和 1&#xff09;和整数k操作&#xff1a;最多可以将k个 0 翻转成 1目标&#xff1a;找到翻转后能得到的最长连续 1 的子数组长度 这个问题的核心是要找到一…

C#单元测试(xUnit + Moq + coverlet.collector)

C#单元测试 xUnit Moq coverlet.collector 1.添加库 MlyMathLib 2.编写库函数内容 using System;namespace MlyMathLib {public interface IUserRepo{string GetName(int id);}public class UserService{private readonly IUserRepo _repo;public UserService(IUserRepo repo…

【数据库】Oracle学习笔记整理之五:ORACLE体系结构 - 参数文件与控制文件(Parameter Files Control Files)

Oracle体系结构 - 参数文件与控制文件&#xff08;Parameter Files & Control Files&#xff09; 参数文件与控制文件是Oracle数据库的“双核基石”&#xff1a;参数文件是实例的“启动配置中心”&#xff0c;定义运行环境与规则&#xff1b;控制文件是数据库的“物理元数据…

GDB典型开发场景深度解析

GDB典型开发场景深度解析 以下是开发过程中最常见的GDB使用场景&#xff0c;结合具体实例和调试技巧&#xff0c;帮助开发者高效解决实际问题&#xff1a;一、崩溃分析&#xff08;Core Dump调试&#xff09; 场景&#xff1a;程序突然崩溃&#xff0c;生成了core文件 # 启动调…

存储、硬盘、文件系统、 IO相关常识总结

目录 &#xff08;一&#xff09;存储 &#xff08;1&#xff09;定义 &#xff08;2&#xff09;分类 &#xff08;二&#xff09;硬盘 &#xff08;1&#xff09;容量&#xff08;最主要的参数&#xff09; &#xff08;2&#xff09;转速 &#xff08;3&#xff09;访…

docker安装mongodb及java连接实战

1.docker部署mongodb docker run --name mongodb -d -p 27017:27017 -v /data/mongodbdata:/data/db -e MONGO_INITDB_ROOT_USERNAMEtestmongo -e MONGO_INITDB_ROOT_PASSWORDtest123456 mongodb:4.0.112.项目实战 <dependencies><dependency><groupId>org.m…

Java设计模式之《工厂模式》

目录 1、介绍 1.1、定义 1.2、优缺点 1.3、使用场景 2、实现 2.1、简单工厂模式 2.2、工厂方法模式 2.3、抽象工厂模式 3、小结 前言 在面向对象编程中&#xff0c;创建对象实例最常用的方式就是通过 new 操作符构造一个对象实例&#xff0c;但在某些情况下&#xff0…