求数组排列的范围

问题描述:给定一个整数数组,将这个整数数组排列成一个整数,并且数组的每个元素都要用到,求所排列出的整数的范围。

分析:这是一个很有意思的题目,初看好像是要求所有排列情况的最小值和最大值,当然这样做也可以求出来,只不过时间复杂度过高,

另外还有一个问题是大数问题,所排列成的数可能范围很大,超过了基本数据类型所能表示的范围,因此需要转换为字符串处理。

下面详细介绍解法:

解法一:用排列法。也就是求出这个数组的全排列,然后求出这个排列的最小值和最大值。由于排列要用到递归实现,

递归一般消耗系统大量的时间和空间,因此该方法效率略低。

解法二:直接求出排列的最大值和最小值。先介绍一种方法,对于两个整数a和b,排列成一个整数后有两种结果ab和ba,

这里我们定义了一种新的大小规则,

如果ab>ba,我们就认为a>b;

如果ab=ba,我们就认为a=b;

如果ab<ba,我们就认为a<b;

这不同于数学中的大小规则,为了解决大数问题,先将整数数组转化为字符串数组,在进行比较。具体算法如下:

第一步:将整数数组转换为字符串数组。

第二步:将这个字符串数组按照我们新定义的大小规则进行排序。

第三步:将排序后的数组串连成一个字符串,这个字符串就是所要求的最小值。

第四步:将第三步字符串逆序就是所要求的最大值。

可以看出整个算法非常巧妙,避免了求排列的过程,整个算法的时间复杂度为O(nlogn).

具体的Java代码如下,写法比较通用,读者可以很容易的转化为其他语言实现:

 1 public class Main {
 2     public static String[] zuheminmax(int a[]){
 3         String b[]=new String[a.length];
 4         for(int i=0;i<a.length;i++)                       //数值转换为字符串
 5             b[i]=new String(a[i]+"");
 6         for(int i=0;i<b.length-1;i++)                     //按照自定义的规则排序
 7             for(int j=i+1;j<b.length;j++)
 8                 if(compare(b[i],b[j]))
 9                 {    String t=b[i];
10                    b[i]=b[j];
11                    b[j]=t;
12                 }
13         String minmax[]=new String[2];                     //用来存储排列数的最小值和最大值
14         minmax[0]=new String("");
15         minmax[1]=new String("");
16         for(int i=0;i<b.length;i++)                       //将所有的数连接起来,组成最小值
17             minmax[0]+=b[i];
18         for(int i=0;i<b.length;i++)                       //将所有的数连接起来,组成最大值
19             minmax[1]=b[i]+minmax[1];
20         return minmax;
21     }
22     public static boolean compare(String a,String b){     //自定义比较规则
23         String ab=a+b;
24         String ba=b+a;
25         if(ab.compareTo(ba)>0)return true;
26         else return false;
27     }
28     public static void main(String[] args) {
29         // TODO 自动生成的方法存根
30        int a[]={12,10,5,6,9};
31        String[] minmax=zuheminmax(a);
32        System.out.println("最小值为:"+minmax[0]);
33        System.out.println("最大值为:"+minmax[1]);
34     }
35 }

输出结果为:

最小值为:1012569
最大值为:9651210

时间: 2024-08-24 19:25:51

求数组排列的范围的相关文章

[Leetcode] subsets 求数组所有的子集

Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be in non-descending order. The solution set must not contain duplicate subsets. For example,If S =[1,2,3], a solution is: [ [3], [1], [2], [1,2,3], [1,

写一个方法求数组中的最大值,最小值,总和以及平均值。

class Program { /// <summary> /// 求数组中的最大值,最小值,总和以及平均值. /// </summary> /// <param name="nums">输入一个数组</param> /// <returns>返回一个新的数组(max,min,sum,avg)</returns> public static int[] GetMaxMinSumAvg(int[] nums) { i

class 3 求数组中的最大值(单元测试)

1.问题引出: int Largest(int list[], int length) { int i,max; for(i = 0; i < (length – 1); i ++ ) { if(list[i] > max) { max=list[i]; } } return max; } 由此段程序编写一个正确的程序实现求数组的最大值. #include <iostream> using namespace std; int Largest(int list[],int leng

[LeetCode] Find Peak Element 求数组的峰值

A peak element is an element that is greater than its neighbors. Given an input array where num[i] ≠ num[i+1], find a peak element and return its index. The array may contain multiple peaks, in that case return the index to any one of the peaks is fi

《github一天一道算法题》:分治法求数组最大连续子序列和

看书.思考.写代码! /*************************************** * [email protected] * blog: http://blog.csdn.net/hustyangju * 题目:分治法求数组最大连续子序列和 * 思路:分解成子问题+合并答案 * 时间复杂度:O(n lgn) * 空间复杂度:O(1) ***************************************/ #include <iostream> using nam

算法题:求数组中最小的k个数

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 题目:输入n个整数,找出其中最小的k个数. <剑指offer>给出了两种实现算法: 算法1:采用Partition+递归法,该算法可以说是快速排序和二分查找的有机结合.算法的时间复杂度为O(n),缺点在于在修改Partition的过程中会修改原数组的值. 算法2:采用top-k算法.如果要找最小的K个数,我们才用一个含有K个值的大顶堆:如果要找最大的K个数,我们采用小顶堆.该算法的时间复杂度为O(nlogK),是一种比较好的算法,启发于堆排序

1、打印二进制机器码,程序内存分析,大端序小端序,指针数组,数组指针,数组的三种访问方式,typedef,#if-0-#endif,求数组大小,括号表达式

 1.打印二进制机器码(分别表示32位的和64位的) #include <stdio.h> /*按照8位的长度打印一个数值*/ void dis8bit(char val) { int bit = 8; while(bit--) { if(1<<bit&val){ printf("1"); } else { printf("0"); } if(!(bit%4)) printf(" "); } putchar(1

用C随机产生的正整数存到数组中,并求数组中的所有元素最大值、最小值、平均值以及各元素之和,及第二大值。

用 C 求一组随机数的第二大值,不能通过对整体排序求得 1 随机产生20个[10 , 50]的正整数存到数组中,并求数组中的所有元素最大值.最小值.平均值以及各元素之和,及第二大值.        int a[20];    int sum = 0; //存储数组元素的和    //为数组赋值    printf("数组中的元素为:\n ");    for (int i = 0; i < 20; i ++) {        a[i] = arc4random() % 41 +

求数组中和为给定值的任意两个数

转载请注明出处:http://blog.csdn.net/ns_code/article/details/24933341     题目: 输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字.要求时间复杂度是O(n).如果有多对数字的和等于输入的数字,输出任意一对即可. 例如输入数组1.2.4.7.11.15和数字15.由于4+11=15,因此输出4和11.     思路: 最直接的做法是暴力法,两个for循环,时间复杂度为O(n*n),但是这样没有充