• 百度面试题:度度熊排序


    题目描述:

      度度熊有一个N个数的数组,他想将数组从小到大排好序,但是萌萌的度度熊只会下面这个操作:

      任取数组中的一个数然后将它放置在数组的最后一个位置。

      

      问最少操作多少次可以使得数组从小到大有序?

    输入描述:

      首先输入一个正整数N,接下来的一行输入N个整数。(N<=50,每个数的绝对值小于等于1000)

    输出描述

      输出一个整数表示最少的操作次数

    输入例子:

      4

      19 7 3 25

    输出例子:

      3

    思路:

      首先我们知道,度度熊只会从数组中拿一个数,放置到最后面;而且,给你的数组是手动给的,未知的。故此,需要找到度度熊每次操作的策略才能够得到最少的操作次数。

      想要最少的操作次数来将排序完成,且是从小到大。所以必须得知道从小到大的排序是什么样子的。

      还有在操作过程中,我们只有在遇到逆序对的时候才会需要操作的。

      这时就发现,逆序对这个概念的存在了。就是形如“……,3,……,1,……”是不满足从大到小,是逆序对,我们绝对需要对其中的大的数进行操作。

      故而就发现,我们每次操作都是先找逆序对,再进行操作。因为是需要从小到大排序,那么得先从最小的逆序对寻找。然后操作较大的数。

      以“19 7 3 25”为例:

          其从小到大排序为“3 7 19 25”,

          故而先看“3”和“7”是否为逆序对,

            如果是那么把“7”移动到最后

          接下来继续看“7”和“19”是否为逆序对,

          以此类推。

    实现:

    import java.util.Arrays;
    import java.util.Scanner;
    
    public class Main {
    	public static void main (String args[]){
    		Scanner sc = new Scanner(System.in);
    		int n = sc.nextInt();
    		int[] a=new int[n];
    		for(int i=0;i<a.length;i++){
    			a[i]=sc.nextInt();
    		}
    		sc.close();
    		int[] b=Arrays.copyOfRange(a, 0, a.length);
    		Arrays.sort(b);
    		int count = 0;
    		for(int j = 0; j< a.length-1;j++){
    			int min = b[j];
    			int max = b[j+1];
    			int minNum = -1;
    			int maxNum = -1;
    			for(int i=0;i<a.length;i++){
    				if(a[i]==min)
    					minNum = i;
    				if(a[i]==max)
    					maxNum = i;
    				if(minNum!=-1 && maxNum!=-1){
    					break;
    				}
    			}
    			System.out.println("minNum:"+b[j]+":"+minNum+"
    maxNum:"+b[j+1]+":"+maxNum);
    			if (maxNum<minNum){
    				count++;
    				int[] aa = Arrays.copyOfRange(a, 0, maxNum);
    				int[] ab = Arrays.copyOfRange(a, maxNum+1, a.length);
    				for(int i = 0;i<aa.length;i++){
    					System.out.print(aa[i]+" ");
    				}
    				System.out.println();
    				for(int i = 0;i<ab.length;i++){
    					System.out.print(ab[i]+" ");
    				}
    				System.out.println();
    				int[] ac = {b[j+1]};
    				System.arraycopy(ab, 0, a, aa.length, ab.length);
    				System.arraycopy(ac, 0, a, aa.length+ab.length, ac.length);
    				for(int i = 0;i<a.length;i++){
    					System.out.print(a[i]+" ");
    				}
    				System.out.println();
    			}
    		}
    		System.out.println(count);
    	}
    }
    

    实现输出

    4
    19 7 3 25
    minNum:3:2
    maxNum:7:1
    19
    3 25
    19 3 25 7
    minNum:7:3
    maxNum:19:0

    3 25 7
    3 25 7 19
    minNum:19:3
    maxNum:25:1
    3
    7 19
    3 7 19 25
    3

      上述显示了3次操作操作的下标、以及对象和中间过程。

  • 相关阅读:
    闲来无事研究研究.Net中的异步编程
    Sql Server 因为触发器问题导致数据库更新报错“在触发器执行过程中引发了错误,批处理已中止”的问题处理
    c# 连接Redis报错:WRONGTYPE Operation against a key holding the wrong kind of value:类型搞混弄出的错误
    VS2013 调试时出现“表达式计算器中发生内部错误”的问题解决办法
    WCF优化的几个常规思路
    UWP汉堡菜单
    C#注册系统全局快捷键
    CXF详细介绍
    hadoop默认3个核心配置文件说明
    在虚拟机配置hive
  • 原文地址:https://www.cnblogs.com/zdtiio/p/6777602.html
Copyright © 2020-2023  润新知