栈实现队列,探求正整数的下一个数

打印 上一主题 下一主题

主题 913|帖子 913|积分 2739

6.用栈模仿队列

题目

用栈来模仿一个队列,要求实现队列的两个基本操作:入队、出队。
思路

用两个栈,一个栈用来存储入队元素,另一个栈用来存储,出队元素。
比如,有两个栈A,B,入队元素,先进入到栈A,每次元素要出队时,就把栈A的元素依次出栈,进入到栈B,再从栈B出栈,来模仿元素出队。
代码
  1. public class QueueByStack {
  2.     private Stack<Integer> stackA = new Stack<>();
  3.     private Stack<Integer> stackB = new Stack<>();
  4.     /**
  5.      * 入队
  6.      * @param element 元素
  7.      */
  8.     public void enQueue(int element){
  9.         stackA.push(element);
  10.     }
  11.     /**
  12.      * 出队操作
  13.      * @return
  14.      */
  15.     public Integer deQueue(){
  16.         if(stackB.isEmpty()){
  17.             if(stackA.isEmpty())
  18.                 throw new RuntimeException("queue is empty...");
  19.             transfer();
  20.         }
  21.         return stackB.pop();
  22.     }
  23.     /**
  24.      * 栈A元素转移到栈B
  25.      */
  26.     public void transfer(){
  27.         while(!stackA.isEmpty())
  28.             stackB.push(stackA.pop());
  29.     }
  30.     public static void main(String[] args) {
  31.         QueueByStack queueByStack = new QueueByStack();
  32.         queueByStack.enQueue(1);
  33.         queueByStack.enQueue(3);
  34.         queueByStack.enQueue(4);
  35.         System.out.println(queueByStack.deQueue());
  36.         System.out.println(queueByStack.deQueue());
  37.         queueByStack.enQueue(5);
  38.         System.out.println(queueByStack.deQueue());
  39.         System.out.println(queueByStack.deQueue());
  40.     }
  41. }
复制代码
7.探求全排列的下一个数

题目

给出一个正整数,找出这个正整数所有数字全排列的下一个数。通俗点说就是在一个整数所包含数字的全部组合中,找到一个大于且仅大于原数的新整数。
如果输入12345,则返回12354。如果输入12354,则返回12435。如果输入12435,则返回12453。
思路

由固定数字组成的数,排列的最大值,肯定逆序排列,排列的最小值,肯定是顺序排列。
如1,2,3,4,5,6这些数字,最大值,是654321,最小值是123456。
给定一个整数,如何找大于且仅大于当前数的新整数呢?
例如,123654,为了和原数靠近,我们要尽量保持高位不变,低位在最小范围内变换顺序。变换顺序的范围大小,却决于当前整数的逆序区域。
什么是逆序区域,就是我们把一个数,从最后一位往前数,数字是顺序排列的区域,就是逆序区域。
比如,123654,其中654就是这个数据的逆序区域。123465,其中65就是这个数据的逆序区域。123456,其中6就是这个数的逆序区域。654321,则整体都是逆序区域,最大值,找不出大于且仅大于原数的整数了。
如何,找出123654的大于且仅大于原数的新整数呢?
我们只须要,找出逆序区域中,大于逆序区域界限前一个数中最小的数,进行交换,然后,将逆序区域,变为顺序,就是了。首先从逆序区域中,找出一个大于界限前一个数,最小的数,与之交换,是保证交换后的数,大于原数。将逆序区域,改为顺序,是为了保证,是排序后的数,大于原数的情况下最小的一个。
例如,123654,逆序区域为654,其中大于3的最小的是4,交换后,是124653,满足大于元素,但不是最小,由于653这个三位的排列,不满足最小的,须要改为顺序排列,356,所以,大于且仅大于原数的新整数,即为124356。
代码
  1. public class NextNumber {
  2.     public static int findNearestNumber(int number){
  3.         int[] numbers = intToIntArray(number);
  4.         int index = findTransferPoint(numbers);
  5.         if(index == 0)//代表数整体都是逆序排列,是所有排列组合中最大的,无法寻找下一位
  6.             return -1;
  7.         exchangeHead(numbers,index);
  8.         reverse(numbers,index);
  9.         return intArrayToInt(numbers);
  10.     }
  11.     /**
  12.      * 寻找逆序区域,注意返回的index还是属于逆序区域
  13.      */
  14.     private static int findTransferPoint(int[] numbers) {
  15.         for (int i = numbers.length - 1; i > 0; i--) {//数从后往前遍历
  16.             if (numbers[i] > numbers[i - 1])//发现后一个数大于前一个数的情况下,就是找到了逆序区域的边界
  17.                 return i;
  18.         }
  19.         return 0;
  20.     }
  21.     /**
  22.      * 交换
  23.      */
  24.     private static int[] exchangeHead(int[] numbers, int index) {
  25.         int head = numbers[index - 1];//逆序区域的前一位数
  26.         //从后往前,第一个大于head的数,就是逆序区域中大于head的最小数,因为是逆序区域
  27.         for (int i = numbers.length - 1; i > 0; i--) {
  28.             if(head < numbers[i]){
  29.                 numbers[index - 1] = numbers[i];
  30.                 numbers[i] = head;
  31.                 break;
  32.             }
  33.         }
  34.         return numbers;
  35.     }
  36.     /**
  37.      * 将int[]数组,从index开始后的数,反转 1,2,4,6,5,3 -> 1,2,4,3,5,6
  38.      */
  39.     private static int[] reverse(int[] num,int index){
  40.         for(int i =index,j = num.length-1;i < j;i++,j--){
  41.             int temp = num[i];
  42.             num[i] = num[j];
  43.             num[j] = temp;
  44.         }
  45.         return num;
  46.     }
  47.     public static void main(String[] args) {
  48.         int number = 123654;
  49.         for(int i = 0; i < 10; i++){
  50.             number = findNearestNumber(number);
  51.             System.out.println(number);
  52.         }
  53.     }
  54.     /**
  55.      * int数,转成各个位构成的int[]
  56.      */
  57.     private static int[] intToIntArray(int number){
  58.         String numAsString = String.valueOf(number);
  59.         int[] digits = new int[numAsString.length()];
  60.         for(int i = 0; i < numAsString.length(); i++)
  61.             digits[i] = numAsString.charAt(i) - '0';//减去'0'的ASCII码值,得到数。char类型在java中可以看作是一个int的数
  62.         return digits;
  63.     }
  64.     /**
  65.      * int[],转成int
  66.      */
  67.     private static int intArrayToInt(int[] numbers){
  68.         StringBuilder sb = new StringBuilder();
  69.         for(int i : numbers)
  70.             sb.append(i);
  71.         return Integer.parseInt(sb.toString());
  72.     }
  73. }
复制代码
只是为了记载自己的学习历程,且本人程度有限,不对之处,请指正。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

西河刘卡车医

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表