华为OD机试3个排序题

1.

  • 输入: 第一行输入数组个数,第二行输入数组,第三行输入N
  • 输出:数组中最大的N个数和最小的N个数的和,这最值的几个数中,有重复的输出-1

通过率75%,哪有问题,目前还不知道,可以参考下

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;

public class Main{
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine()){
            int count = scanner.nextInt();
            int[] arr = new int[count];
            for(int i=0;i<count;i++){
                arr[i] = scanner.nextInt();
            }
            int num = scanner.nextInt();
            if(num<=0){
                System.out.println("-1");
            }else{
                Arrays.sort(arr);
                List<Integer> result = new ArrayList<>();
                //min
                for (int i = 0; i < num; i++) {
                    result.add(arr[i]);
                }
                //max
                for (int i = arr.length-1; i >= arr.length-num; i--) {
                    result.add(arr[i]);
                }
                List<Integer> collect = result.stream().distinct().collect(Collectors.toList());
                if(collect.size()<num*2){
                    System.out.println("-1");
                }else{
                    int a =0;
                    for (Integer integer : collect) {
                        a+=integer;
                    }
                    System.out.println(a);
                }
            }
        }

    }
}

2.

  • 输入:一组用英文半角逗号隔开的数字字符串
  • 输出:由3个数字组合成最小的数字(不足3个元素则输出所有的)

当时是穷举了,通过率65%,现在是用递归做,进行优化过的

	public static void main(String[] args) throws IOException {
        Scanner scan = new Scanner(System.in);
        String[] split = scan.next().split(",");
        List<String> list = Arrays.stream(split).collect(Collectors.toList());
        List<String> result = new ArrayList<>();
        DFS(result, list, "");
        result.sort(String::compareTo);
        System.out.println(result.get(0));
    }

    public static void DFS(List<String> result, List<String> candidate, String prefix) {
        if (prefix.length() != 0 && candidate.size() == 0) {
            result.add(prefix);
        }
        for (int i = 0; i < candidate.size(); i++) {
            List<String> temp = new LinkedList<>(candidate);
            int item =  Integer.valueOf(temp.remove(i));  // 取出被删除的元素,这个元素当作一个组合用掉了
            DFS(result, temp, prefix + item);
        }
    }

3.

和第二题有点像

  • 输入:一组数 如: 10 9 21
  • 输出:3个元素组成的最大的数字(输出字符串)

当时通过率50%多,现在是同样递归优化过的

public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String input = reader.readLine();
        String[] split = input.split(" ");
        List<String> list = Arrays.asList(split);
        List<String> result = new ArrayList<>();
        DFS(result, list, "");
        result.sort(String::compareTo);
        System.out.println(result.get(result.size()-1));
    }

    public static void DFS(List<String> result, List<String> candidate, String prefix) {
        if (prefix.length() != 0 && candidate.size() == 0) {
            result.add(prefix);
        }
        for (int i = 0; i < candidate.size(); i++) {
            List<String> temp = new LinkedList<>(candidate);
            int item =  Integer.valueOf(temp.remove(i));  // 取出被删除的元素,这个元素当作一个组合用掉了
            DFS(result, temp, prefix + item);
        }
    }

上面2 3 题 思路就是,递归求出所有的排列,排序后拿出最小值


补充

对于上面2 3题,新的解法

	public static String minDictOrderOfStringJoint(String[] arr){
        if(arr == null || arr.length == 0)
            return "";
        Arrays.sort(arr, (o1, o2) -> o1.concat(o2).compareTo(o2.concat(o1)));
        StringBuffer sb = new StringBuffer();
        for(int i = 0; i < arr.length;i ++){
            sb.append(arr[i]);
        }
        return sb.toString();
    }

利用Comparator接口进行排序,排序规则是,两两比较,较大或较小的排前面即可

或者可以使用位数的比较,取大值时,1位数的最大值放第一位,以此类推.最小值时最大位数的最小值做第一位

  • 0
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qlanto

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值