(真)n选m排列算法next_permutation() 非递归版本

C++:全排列函数next_permutation()和prev_permutation() 文章目录前言一、next_permutation()用法二、prev_permutation()用法总结 前言 字节三面,考了leetcode556题,复盘发现了两个超好用的函数,C++STL中的全排列函数为两个:next_permutation和prev_permutation 其中:next_permutation实现升序,而prev_permutation实现降序。 一、next_permutation()用法 二、prev_permutation()用法 总结 学习永无止境! ... 阅读详情
/**
 *@auther 皇阿玛
 *2019/9/16 13:51
 */

package courseOne;

import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;


class Permutation{//递归方法,要找一个非递归的方法
	int total;
	static int count=0;
//	private int[] people;
	public Permutation(){}
	public Permutation(int total,int SelectPeople){
//		this.people = new int[SelectPeople];
		this.total = total;
	}
	public boolean next(List<Integer> lis,int start){
		if(start >= lis.size() ){
			System.out.println(lis);
			count++;
			return true;
		}
		for(int i=1;i<=total;i++){
			if( !lis.contains(i) ){
				lis.set(start, i);
			}else{
				continue;
			}
			next(lis,start+1);
			lis.set(start, -1);
		}
		return true;
	}
	public boolean next2(List<Integer> lis){//非递归写出来
		int flag = 0;//用来判断初始list是否全为0,则需要赋初值1,2,3...
		int ChangeFlag = 0;//用来判断是否已经对list进行更新了,若已更新,则直接退出并返回true
		for(int i=0;i<lis.size();i++){
			flag += lis.get(i);
		}
		if(flag == 0){//初始化
			for(int j=0;j<lis.size();j++){
				lis.set(j, j); //lis.set(index, element)
			}
			ChangeFlag = 1;
		}else{
			for(int k=lis.size()-1;k>=0;k--){
//				System.out.println("1.k = "+k);/////////////////////////////
				if(!IsMaxOrNot(lis,k) && ChangeFlag == 0){//最后一位不是最大值的话,就进行最小增值
					if( LittleIncrease(lis,k) )
						ChangeFlag = 1;
					//break;
					//若最后一位是最大值,则  k 进入下一层for循环,即把lis中的搜索位置前移
					//若更新的位置k不是最后一位,则需要对k位之后的数据进行从小到大更新!
					if(1 == ChangeFlag ){//如果最小更新的元素位置是k的话=>&& k < lis.size()
//						System.out.println("I'm complemening!!!,k = "+k+" lis = "+lis);
						Complement(lis,k);//对k之后的元素进行按顺序补全
					}
					break;
				}	
			}
		}
		if(1 == ChangeFlag)
			return true;
		else
			return false;
	}
	
	public boolean IsMaxOrNot(List<Integer> lis,int loc){//loc从0开始计数
		int[] tem = new int[total];//初值为0;
		Arrays.fill(tem, 0);	    //对数组用某个数进行填充
		int flag = 1;				//判断标志,默认是最大值,则flag=1,若不是最大值,则令flag=0;
		
		for(int i=0;i<lis.size() && i<loc;i++){//对loc之前&&已用过的 元素进行标记
			tem[lis.get(i)] = 1;
		}
		for(int j=0;j<total;j++){  //未用过的元素中去比较查找是否有更大的元素
			if(tem[j] != 1 && j>lis.get(loc))//数值 j 没用过,而且 j 比lis第loc位的数值要大。
				flag = 0;		   //说明list.get(loc)不是最大值,还有更大的数值可选
		}
		if(0==flag) 
			return false;
		else
			return true;
	}
	public boolean LittleIncrease(List<Integer> lis,int loc){//当某个位置的数值不是最大值时,进行最小限度地增加
		int[] tem = new int[total];//初值为0;
		Arrays.fill(tem, 0);	    //对数组用某个数进行填充
		int flag = 0;				//判断标志,默认是最大值,则flag=1,若不是最大值,则令flag=0;
		
		for(int i=0;i<lis.size() && i<loc;i++){//对loc之前&&已用过的 元素进行标记
			tem[lis.get(i)] = 1;
		}
		for(int j=0;j<total;j++){  //未用过的元素中去比较查找是否有更大的元素
//			System.out.println("2.lis.get(loc) = "+lis.get(loc)+" loc = "+loc);
			if(tem[j] != 1 && j>lis.get(loc)){//数值 j 没用过,而且 j 比lis第loc位的数值要大。
				lis.set(loc, j);   //把loc位置的数值增加为j;!!!!!!!!!!!!
				flag = 1;		   //完成增值工作
//				System.out.println("3.list = "+lis);
				break;
			}
		}
		if(0==flag){
//			System.out.println("false");
			return false;
		}
			
		else{
//			System.out.println("true");
			return true;
		}
			
	}
	public boolean Complement(List<Integer> lis,int loc){//loc是中间更新的位置下标(index) <=> k
		//当处理完的最小增值位置不是在最后一位时,需要对 后面 元素进行补全,按照剩余元素,从小到大处理;当前的 loc 位置  不用改动 !!!!!
		int[] tem = new int[total];//初值为0;
		Arrays.fill(tem, 0);	    //对数组用某个数进行填充
		//int flag = 1;				//判断标志,
//		System.out.println("4.in Complement,loc = "+loc+", lis = "+lis);
		for(int i=0;i<=loc;i++){//对loc之前&&已用过的 元素进行标记(loc就是下标,直接带入index)  :i<lis.size() && 
			tem[lis.get(i)] = 1;				//这里loc要记得取等号
		}
		
		for(int j=loc+1;j<lis.size();j++){//j:每个待修正的位置坐标!!!对loc之后的元素进行重新洗牌,坐标从(loc+1)开始走
			int ChangeFlag = 0;//修补过程,已进行到的 位置 下标!!!
			for(int k=0;k<total && ChangeFlag == 0;k++){
				if(tem[k]!=1){
					lis.set(j, k);
					ChangeFlag = 1;
					//ChangeFlag++;
					tem[k] = 1;
//					System.out.println("5.lis = "+lis+", k = "+k+", loc = "+loc+", Changeflag="+ChangeFlag);
				}
			}
		}
		return true;
	}
	
}


public class PermutationExample {
	public static void main(String[] args){
		
		int sum = 0;
		int total = 5;
		int need = 3;// n <=> SelectPeople
		List<Integer> lis = new ArrayList<Integer>();
		List<String> lis2 = new ArrayList<String>();
//		lis2.add("q");
//		lis2.get(0);
//		System.out.println("ss");
		for(int i = 0 ; i < need;i++) {
			lis.add(0);
		}
		Permutation perm = new Permutation(total,need);
		
		
		while(perm.next2(lis)){
			System.out.println(lis);
			sum++;
		}
		System.out.println("The num of permutations is "+sum+" !!!");
//		while(sum>0){
//			perm.next2(lis);
//			System.out.println(lis);
//			sum--;
//		}
	}
}
		/**
		 * 
		 
		List<Integer> lis = new ArrayList<Integer>();
		for(int i = 0 ; i < need;i++) {
			lis.add(-1);
		}
		
		Permutation per = new Permutation(total,need);
		per.next(lis, 0);
//		int sum = 60;
//		while( sum>0 ){
//			per.next(lis, 0);
//			System.out.println(lis);
//			sum--;
//		}
		System.out.println("all of the number:"+per.count); 
		*/

 

全排列问题算法及实现(Permutation) 前言 做项目遇到数据采集系统中ADC拼合问题,如果顺序不对,波形就是错误的(题外话),为了找到正确的顺序,涉及到排列问题。 什么是排列组合 定义 一般地,从n个不同元素中取出m(m≤n)个元素,按照一定的顺序排成一列,叫做从n个元素中取出m个元素的一个排列(Arrangement)。特别地,当m=n时,这个排列被称作全排列(Permutation)。  Ex:考虑三个数字1,2,3,这个序... 阅读详情

相关推荐

vllm运行过程中出现cuda out of memory

将长序列分解为多个小块,每个块分别处理。这样可以减少单次 Prefill 的计算量和显存占用,从而优化 TTFT 和显存使用效率。考虑使用 CPU 卸载(如 --cpu-offload-gb),将部分缓存卸载到 CPU 内存中,扩展 GPU 的虚拟内存。在大语言模型中,当输入序列很长(例如超过 1024 个 Token)时,Prefill 阶段的计算量会非常大。最后增加了enable-chunked-prefill参数和max_num_batched_tokens解决了问题。参数来进一步优化性能。

盛世芳华 3517

N个数取m个数的全排列非递归

全排序的非递归实现

lin200753的专栏 4575

车载以太网抓包实战:100BASE-T1/1000BASE-T1高效监控方案解析

本文深入解析了车载以太网100BASE-T1/1000BASE-T1的高效抓包监控方案。针对智能汽车开发中的故障排查与性能测试需求,详细对比了交换机镜像、TAP分流和捕获模块三大主流方案的原理、核心优势与适用场景,并提供了基于实战经验的选型指南与操作避坑要点,帮助工程师精准定位网络问题。

desk3的博客 428

从N个元素挑出M个组合的算法

1. 将i 从0到(2的N平方-1)递增,依次寻找i的二进制中1的个数,如果为m,则进行后续操作。 2. 递归调用函数: 这个是示例代码(待补充): #include<iostream>using namespace std;const int MAX=10;int g[MAX],N,M;void zuhe(int n,int m){ for (int...

1549

JSAPI微信支付(小程序)V3版本JAVA代码实战源码

1.1、商户通过JSAPI/小程序下单接口获取到发起支付的必要参数prepay_id后,再通过微信小程序调起微信支付收银台JSAPI/小程序下单_JSAPI支付|微信支付商户文档中心1.3、微信H5发起类似,结合文档,细微调整,前端返回类似,参考文档修改为微信内置浏览器调起支付即可。

java web 707

NVMe-MI 协议解析:带外管理框架与实现原理

本文深入解析了NVMe-MI协议,这是一种用于NVMe固态硬盘的标准化带外管理接口。文章详细阐述了其独立于操作系统的管理框架,通过MCTP协议栈实现,支持SMBus/I2C、PCIe VDM和I3C等物理层,从而在系统故障时仍能可靠地进行健康监控、固件升级等关键运维操作,是现代数据中心存储管理的核心基础设施。

lll78的博客 961

利用分治思想,写一个求解从n个元素里选取m个有多少种组合方案的(非递归)高性能算法

从一个简单的例子说起,比如现在一个数组[0,1,2,3,4,5,6],要求不重复选取4个,请问有多少种组合。我们按照从小到大的顺序罗列了15种结果:(粗体表示但前指针位置) 组合数 对应的偏移量数组 [0,1,2,3], [0,0,0,0] [0,1,2,4], [0,0,0,1] [0,1,2,5], [0,0

baidu_38487648的博客 1704

新版本大疆智图4.5 永久许可摄影测量建模软件

大疆智图支持常见格式的成果输出,包括 TIFF 正射影像和高程模型、LAS 格式点云,以及 B3DM、OSGB、OBJ 等六种常用格式的三维模型,还包括 DXF 和 SHP 等格式的等高线。大疆智图 DJI Terra是领先的三维重建软件,提供先进的技术和简单的操作,一站式解决方案,从航线规划到数据的获取,以及模型重建、数据分析等都提供独一无二的支持,优化项目工程,提供自动化优势,获得更有效智能的决策和行动,最终用户可以获得理想的结果,减轻工作压力,提高作业效率。质量报告和剖面查看功能有助于分析点云质量。

qq_62821232的博客 6902

从n个数中选取m个数的所有组合

非递归实现: #include #define N 7 #define M 3 int main() { int array[N] = { 1,2,3,4,5,6 ,7 }; int i, j, k; for (i = 0; i<=N-M; i++) for (j = i + 1; j<=N-M+1; j++) for (k = j + 1; k<=N-M+2;

microlyc的博客 2万+

病理组学分析系列教程1:使用Python-histolab进行病理图像预处理,tiles切片自动生成

病理图像tiles自动生成,WSI图像预处理

qq_43449643的博客 1741

【原理图PCB专题】Cadence 17.4版本原理图及PCB 模块复用

在我们设计复杂板卡的时候,往往会遇到一部分电路被反复使用的情况。Cadence允许设计者一开始就将复用模块设计好,以后只要直接调用复用模块就可以直接用以设计更复杂的电路板了。这对于大规模集成设计无疑是非常好的选择,它不仅让设计者不必花费时间在相同模块反复设计上,更有利于电路的模块化设计。

一点硬件 2017

c++全排列 next_permutation()函数

c++全排列 转载博客:https://www.cnblogs.com/cstdio1/p/11311500.html 对于next_permutation函数,其函数原型为: #include < algorithm> bool next_permutation(iterator start,iterator end) 当当前序列不存在下一个排列时,函数返回false,否则返回tru...

zlzhujust@gmail.com 3392

Linux Kernel入门到精通系列讲解(RV-Kernel 篇) 5.5 RTC设备编写与实现

4. Linux kernel RTC子系统goldfish_rtc driver分析。电脑,会需要时间,还比如 我们的手机、平板,都需要时间;驱动基本就是应用层需要什么数据你给什么数据就行,基本必须实现的就是。3.2 Linux kernel RTC 设备描述符讲解。中看到他的具体实现,也可以根据他的寄存器描述直接在。5. 将驱动添加进kernel和测试RTC驱动。系统来说,时间是一个非常重要的功能;之类的函数接口,接下来我们就开始讲解如何写。,所以我们直接移植设备树即可。,他的寄存器很简单,你可以从。

DSMGUOGUO的博客 569

Wand-Enhancer 免费解锁 WeMod 专业版:三步本地补丁完整指南

WeMod 的专业功能都锁在订阅后面,不想按月付费?Wand-Enhancer 是一个开源本地补丁工具,全程离线改写 WeMod 客户端文件,免费完整解锁专业版,零网络请求、零成本。 ## 先说做完能拿到什么 跑通之后,你的 WeMod 账号会直接显示专业版(年费、已激活):原本受限的修改器库全部开放,实时修改与快捷键正常生效,主题与本地增强布局可选应用。如果打上了远程面板补丁,手机扫码同一局

gitblog_00109的博客 960

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

next_permutation函数简要

next_permutation函数 文章目录next_permutation函数前言一、int 类型的next_permutation二、char 类型的next_permutation三,例题总结 前言 输入一个序列,每调用一次,可以求出输入序列的下一个序列,可以遍历全排列,要包含头文件 与之完全相反的函数还有prev_permutation 一、int 类型的next_permutation 代码如下(示例): int main(){ int a[3]; a[0]=1;a[1]=2;

weixin_53518090的博客 3881

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

全排列生成算法:next_permutation

转自: http://www.cnblogs.com/devymex/archive/2010/08/17/1801122.html欢迎看原博客!概念全排列的生成算法有很多种,有递归遍例,也有循环移位法等等。C++/STL中定义的next_permutation和prev_permutation函数则是非常灵活且高效的一种方法,它被广泛的应用于为指定序列生成不同的排列。本文将详细的介绍prev_p

好记性不如烂笔头的专栏 582

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

STL求下一个全排列算法 next_permutation

next_permutation STL提供了两个用来计算排列组合关系的算法,分别是next_permutation和prev_permutation。 next_permutation通常用于生成序列的全排列。 用法 int a[] = {1, 2, 3} do{ cout << a[0] << " " << a[1] << " " << a[2] << endl; }while(next_permutatio

m0_61506053的博客 797

全排列next_permutation(c,c+a)

Ignatius and the Princess IITime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 9858    Accepted Submission(s): 5760Problem Description Now our hero...

henucm的博客 488

N个数全排列的第M个排列是?(全排列)

给你N个整数,分别是1,2,3,。。。N。问你全排列的第M个排列为多少? Input 输入包含几个测试用例。每个测试用例由两个数字组成,N和M(1<=N<=1000, 1<=M<=10000). 你可能会假设总有一个序列满足题目需求。输入在文件结束时终止。 Output 对于每个测试用例,您只需要输出满足题目要求的序列。输出序列时,应该在两个数字之间打印空格,但不要...

weixin_44373494的博客 2206

STL之全排列函数 next_permutation

next_permutation函数将按字母表顺序生成给定序列的下一个较大的排列,直到整个序列为降序为止 prev_permutation函数与之相反,是生成给定序列的上一个较小的排列。二者原理相同,仅遍例顺序相反 解决问题: eg: 1.给定非空序列,生成递增或递减序列 2.从n个数中选择m个数,按字典序输出其排...

点点滴滴 332

hdu1027(n个数的按字典序排列的第m个序列)

题目信息:给出n,m,求n个数的按字典序排列的第m个序列 http://acm.hdu.edu.cn/showproblem.php?pid=1027 AC代码: /**  *全排列的个数(次序)  */ #include #include #include int a[1001],x; using namespace std; void print(int n)

机器笨猫 6091

全排列next_permutation函数

POJ1833 全排列问题 查看题目点击此链接 分析: 此问题用到next_permutation函数则很容易 next_permutation函数是求当前排列的下一个排列 next_permutation(a,a+n);//求下一个排列 prev_permutation(a,a+n);//求上一个排列 //如果没有上一个排列或下一个排列则返回false,否则true //还可以定义cmp来定义排列的方式next_permutation(a,a+n,cmp) 知道了这个函数那么题目就简单了很多 inclu

wzy1414的博客 298

全排列的生成使用C++的库函数:next_permutation

全排列的生成算法有很多种,有递归遍例,也有循环移位法等等。但C++/STL中定义的next_permutation和prev_permutation函数则是非常灵活且高效的一种方法,它被广泛的应用于为指定序列生成不同的排列。本文将详细的介绍prev_permutation函数的内部算法。

Follow My Heart 2896

【ACM】与全排列相关的STL函数 prev_permutation next_permutation

排列  与  全排列 从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。 当m=n时所有的排列情况叫全排列。如果这组数有n个,那么全排列数为n!个。 对于全排列的求解可以使用递归,这里介绍几个方便的函数(),得到全排列。 对于序列{ 'a' , 'b' , 'c' }(之后为了方便,不打单引号,嘻嘻),每一个元素都比后面的小,按照字...

( :3 ) 418

next_permutation

next_permutation(): 求“下一个”排列组合 例如 三个字符{a, b, c}组成的序列, next_permutation()能按字典序返回6个组合: abc,acb,bac,bca,cab,cba 函数next_permutation()的定义有两种形式: bool next_permutation (BidirectionalIterator first, Bi...

chen_zan_yu_的博客 199
上一篇: kmeas算法,最菜学法,一点一点注释学习
下一篇: n选m 组合 算法的next函数(非递归方法)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值