#题目:
有n个正整数(每个数小于10亿),将它们表示成字符串形式。对每一个字符串s,
可以翻转为新字符串s’,如“1234”可以翻转成“4321”。现在,
将这n个字符串以任意顺序连成一个字符环,每个字符串可以选择是否翻转。在字符环中,
从任意一个位置开始,遍历整个环,得到一个长整数。请问,如何才能得到最大的长整数

举例:9,98,23,56,56,998 1
要反转的 :23->32 56->65
得到数组: 9 98 32 65 65 998 1 最后得到的最大的长整数是 9 998 98 65 65 32 1
#method 正确的解法:字符串排序 这题的考点是字符串排序,而非数字排序。 在排序过程中使用 Comparator 比较两个排序的字符串。

compareTo() 的返回值是 int, 它是先比较对应字符的大小( ASCII 码顺序)

  1. 如果字符串相等返回值0
  2. 如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的差值(ascii码值)(负值前字符串的值小于后字符串,正值前字符串大于后字符串)
  3. 如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至比较的字符或被比较的字符有一方全比较完,这时就比较字符的长度.

对于 [830,8301],若纯粹使用 compareTo 方法无法得到正确解。 技巧在于先将两个字符串以不同的两种方式( right-to-left 或 left-to-right)连接后,再比较它们的大小。

class Solution {
	//本题最好的方式采用字符串排序的方式

    public String largestNumber(int[] nums) {
    	if(nums.length<=0){
    		return null;
    	}
    	String[] strs = new String[nums.length];
    	for (int i = 0; i < nums.length; i++) {
			strs[i] = String.valueOf(nums[i]);
		}
    	
    	Arrays.sort(strs,new Comparator<String>() {

			@Override
			public int compare(String o1, String o2) {
				// TODO Auto-generated method stub

				//return o1.compareTo(o2);   //这是正常的排序

				String  leftRight = o1+o2;
				String  rightLeft = o2+o1;
				return  -leftRight.compareTo(rightLeft);
			}
		});
    	
    	StringBuilder sb = new StringBuilder();
    	for (String str : strs) {
    		System.out.print(str+"  ");
			sb.append(str);
		}
    	while(sb.length()>1 && sb.charAt(0)=='0'){
    		sb.deleteCharAt(0);
    	}
    	return sb.toString();
    }
}

#method (这是错误的!!!)思路:建立一棵字典树 trie 比如:
我们可以把这一组数构建一棵字典树
字典树 字典树相当于二叉树的复杂版本
同时我们可以构建字典树的同时统计词的词频
词频字典树 构造好字典树后,我们采用遍历的方式来获取词以及词频,输出的数正好是我们需要的顺序

上代码:

class TreeNode{
	int val;
	int freq = 0;      //统计词频

	int MAX_SIZE = 10;
	TreeNode[] digits;
	TreeNode(int x){
		this.val = x;
		digits = new TreeNode[MAX_SIZE];   //对象默认赋值为空

	}
}

class Trie{
	TreeNode root;
	Trie(){
		root = null;   
	}
	
	public void insertOneInteger(int num){
		if(root == null){
			root = new TreeNode(-1);
		}
		TreeNode cur = root;
		int[] arr = int2Arr(num);
		for (int i = 0; i < arr.length; i++) {
			if(cur.digits[arr[i]]==null){
				cur.digits[arr[i]] = new TreeNode(arr[i]);   //不为空,则建一个节点

			}
			cur = cur.digits[arr[i]];
			if(i == arr.length-1){         //统计单词的词频

				cur.freq+=1;
			}   
		}
	}
	
	public void buildTrie(int[] nums){   //构建字典树

		for (int i = 0; i < nums.length; i++) {
			insertOneInteger(nums[i]);
		}
	}
	
	public void PreOrderTravelse(TreeNode root){   //优先遍历我们的字典树

		if(root == null){
			return;
		}else{
				System.out.print(root.val + "=="+root.freq+"  ");
			for (int i = 0; i < root.MAX_SIZE; i++) {
				PreOrderTravelse(root.digits[i]);
			}
			
		}
	}
	
	public ArrayList<ArrayList<Integer>> LevelOrderTravelse(TreeNode root){  //层序遍历我们的字典树

		ArrayList<ArrayList<Integer>> arrs = new ArrayList<>();
		if(root == null){
			return arrs;
		}
		ArrayList<Integer> arr = new ArrayList<>();
		Queue<TreeNode> que = new LinkedList<>();
		Queue<Integer> queLevel = new LinkedList<>();
		que.add(root);
		queLevel.add(0);
		int level = 0;
		while(que.size()>0){
			if(queLevel.peek()>level){   //说明进入下一层了

				arrs.add(arr);
				arr = new ArrayList<>();
				arr.add(que.peek().val);
			}else{
				arr.add(que.peek().val);
			}
			for (int i = 0; i < root.MAX_SIZE; i++) {
				if(que.peek().digits[i]!=null){
					que.add(que.peek().digits[i]);
					queLevel.add(queLevel.peek()+1); 
				}
			}
			level = queLevel.peek();
			que.poll();
			queLevel.poll();
		}
		arrs.add(arr);
		return arrs;
	}
	
	private int[] int2Arr(int num){    //将一个整数转换为数组

		int[] arr = new int[intLen(num)]; 
		int count = intLen(num)-1;
		while(num>0){
			arr[count] = num%10;
			num /= 10;
			count--;
		}
		return arr;
	}
	private int intLen(int num){      //求一个整数的长度

		if(num<0){
			return 0;
		}
		if(num == 0){
			return 1;
		}
		int count = 0;
		while(num>0){
			num/=10;
			count++;
		}
		return count;
	}

	public int depth(TreeNode root){
		return LevelOrderTravelse(root).size();
	} 
	
	public ArrayList<String> TrieTreePath(TreeNode root){   //取出我们词  遍历

		ArrayList<String> paths = new ArrayList<>();
		if(root == null){  //这一层是根节点

			return paths;
		}
		helper(root,"",paths);
		return paths;
	}
	
	private void helper(TreeNode root,String path,ArrayList<String> paths){
		
		boolean flag = true;
		for (int i = 0; i < root.MAX_SIZE; i++){
			flag  = (flag&& (root.digits[i] == null));
		}
		if(flag == true){   //说明到了叶子节点

			paths.add(path+"|"+root.freq);
			return;
		}       
		
		if(root!= null && (root.freq>0)){   //其中某个节点词频 > 0  也需要把路径加入到paths

			paths.add(path+"|"+root.freq);
		}
		for (int i = root.MAX_SIZE-1; i >=0; i--) {
			if(root.digits[i]!=null){
				helper(root.digits[i],path+root.digits[i].val,paths);
			}
		}
	}
	
	//将词频字符串转换为长整数

	public String getLongInteger(ArrayList<String> arrs){
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < arrs.size(); i++) {
			String arr = arrs.get(i);
			String[] splits = arr.split("\\|");
			int count = Integer.parseInt(splits[1]);
			for (int j = 0; j < count; j++) {
				sb.append(splits[0]);
			}
		}
		
		return sb.toString();
	}
	
}

我们可以看出来字典树可以大大压缩数据,节省空间,大树据处理的利器