字节跳动——最大映射(Java解析与解答,以及sort排序)

此题来自牛客网-字节跳动2017后端工程师实习生笔试题

题目

  • 题目:
    有 n 个字符串,每个字符串都是由 A-J 的大写字符构成。现在你将每个字符映射为一个 0-9 的数字,不同字符映射为不同的数字。这样每个字符串就可以看做一个整数,唯一的要求是这些整数必须是正整数且它们的字符串不能有前导零。现在问你怎样映射字符才能使得这些字符串表示的整数之和最大?

  • 输入描述:
    每组测试用例仅包含一组数据,每组数据第一行为一个正整数 n , 接下来有 n 行,每行一个长度不超过 12 且仅包含大写字母 A-J 的字符串。 n 不大于 50,且至少存在一个字符不是任何字符串的首字母。

  • 输出描述:
    输出一个数,表示最大和是多少。

  • 示例1:

    • 输入:

      2
      ABC
      BCA
      
    • 输出:

      1875
      

题解

  • 解析:

    // 第一步
    ABC=100×A+10×B+C
    BCA=100×B+10×C+A
    ABC+BCA=110×B+101×A+11×C
    要使和最大,则权值越大的映射的数字应越大
    所以:B9A8C7
    
    // 第二步
    需要判断权重为0的是否为头字母,如果是0,则和权值为1的替换;若1也不满足,则继续向上替换(类似冒泡)
    
  • 解答:

    import java.util.Comparator;
    import java.util.Scanner;
    import java.util.Arrays;
    import java.lang.Math;
    
    public class Main{
        public static void main(String[] args){
            // 1/输入
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            String[] strs = new String[n];
            for(int i=0; i<n; i++){
                strs[i] = sc.next();
            }
    
            // 2/计算出现次数 和 首字母
            Element[] chs = new Element[10];
            for (int i = 0; i < 10; i++) { // 注意需要初始化
                chs[i] = new Element();
            }
            for(int i=0; i<n; i++){
                int len = strs[i].length();
                char c = strs[i].charAt(0);
                chs[strs[i].charAt(0) - 'A'].flagHeadCh = true; // 是否为首字母
                for(int j=0; j<len; j++){
                    chs[strs[i].charAt(j) - 'A'].times += (int)Math.pow(10,len-j-1); // 计算出现次数
                }
            }
    
            // 3/排序(从大到小)
            Arrays.sort(chs, new Comparator<Element>() {
                        @Override
                        public int compare(Element e1, Element e2) {
                            return e1.times < e2.times ? 1 : (e1.times == e2.times ? 0 : -1);
                        }
                    }
            );
    
            // 4/赋权值
            for(int i=0; i<10; i++){
                chs[i].weight = 9-i;
            }
    
            // 5/调整权值,使首字母不为0
            for(int i=9; i>0; i--){ // 类似于冒泡排序
                if(chs[i].flagHeadCh){
                    chs[i].weight = chs[i-1].weight;
                    chs[i-1].weight = 0;
                }else{
                    break;
                }
            }
    
            // 5/根据权值,计算和
            int sum = 0;
            for(int i=0; i<10; i++){
                sum += chs[i].weight * chs[i].times;
            }
            System.out.println(sum);
        }
    
        static class Element {
            long times; //出现次数
            boolean flagHeadCh; //是否为首字母,即权值是否可以为0
            int weight; //权值
        }
    }
    

注意事项

  • Scanner
如果使用sc.nextLine();
需要注意使用完sc.nextInt()后还需要再加一个sc.nextLine();,使其换行

或者使用sc.next();
  • 新建的类,注意在使用前需要new
  • 排序
// 正序
int[] array = {10, 3, 6, 1, 4, 5, 9};
Arrays.sort(array);
// 逆序
Integer[] arr = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
Arrays.sort(arr, Collections.reverseOrder()); // 注意这里要是类,不能是基本数据类型,可转换为数据包装类
int[] arr2 = Arrays.stream(arr).mapToInt(Integer::valueOf).toArray();
// Comparable方式:在实体中实现Comparable<实体>接口,重写compareTo方法
public class Student implements Comparable<Student> {
	private String name;
	private Integer age;

	public int compareTo(StudentAsc o) {
  		if(null == this.age) {
      		return -1;
  		}
  		if(null == o.getAge()) {
      		return 1;
  		}
  		return this.age.compareTo(o.getAge());
	}
}
// Comparator方式:使用Collections.sort(List list, Comparator<? super T> c)
Collections.sort(students, new Comparator<Student>() {
 	public int compare(Student o1, Student o2) {
    	if(null == o1.getAge()) {
        	return -1;
    	}
   	 	if(null == o2.getAge()) {
        	return 1;
   	 	}
   	 	return o1.getAge().compareTo(o2.getAge());
 	}
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值