2019届华为秋招笔试题【数字反转相加】【消除重复数字】【仿LISP运算】

数字反转相加

1.题目描述

请您写一个 reversoAdd函数,该函数根据输入的两个正整数a和b, 字按照高位在右边的方式反转后求和。
例如,reverseAdd(123, 456) == 321 + 654 = 975
输入描述:
函数原型: int reverseAdd (int a, int b);
输入:
输入的a, b参数均为有效取值范围[1, 70000]区间上的正整数。100和200反转后的值为1和2 (前导0被忽略)
输出描述:
输出:
通过函数返回值输出结果。
若输入的a或b参数超出了取值范围(小于1或者大于70000),则应输出-1:否则应按照要求输出数字反转后的和。
注意:最终交付的函数代码中不要向控制台打印输出任何信息。
输入样例:
123, 456
输出样例:
975

2.解题思路

想法就是把它变成String类型,再利用String类型的reverse()函数进行反转,再将其变成Integer类型进行运算

3.代码

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sr = new Scanner(System.in);
        int a = sr.nextInt();
        int b = sr.nextInt();
        reverseAdd(a,b);
    }
    public static int  reverseAdd(int a,int b){
    		if((a<=1 && a>=70000) || (b<=1 && b>=70000))
    				return -1;
           String  str1 =new StringBuilder(a +"").reverse().toString();
           String str2 =new StringBuilder( b +"").reverse().toString();
           return Integer.parseInt(str1) +Integer.parseInt(str2);
    }
}

消除重复数字

1.题目描述

给定一个正整数,给出消除重复数字以后最大的整数
输入描述:
正整数,注意考虑长整数
输出描述:
消除重复数字以后的最大整数输入样例:423234输出样例:432

2.解题思路

方法1:(垃圾选手第一式,复杂度高)

  • 用list1存放出现一次的数字,用list2存放重复的数字。然后将他们放到优先队列自动排序,因为优先队列从小到大排序的,所以重写它的比较方法new Comparator()…,最后再依次将他们按顺序加到res里面

方法2:

  • 桶排序思想,因为数字无疑就是0-9,所以创建一个长度为10的数组,将每个数字依次入桶。桶中不为空代表这个常整数有该值,然后将桶内的数依次拼凑成最大的数。count[0] ~count[9]依次存放0-9
  • 设置一个list存放一共出现了几个不同的数了,当list.size == 10,代表所有数字都出现过了,后面再怎么出现的数都是重复的。可以提前终止while语句。

3.代码

方法1:

public static long solution(long a) {
        //存放出现一次的数
        List<Integer> list1 = new ArrayList<>();
        //存放重复的数
        List<Integer> list2 = new ArrayList<>();
        while (a != 0) {
            int temp = (int)a % 10;
            if (!list1.contains(temp) && !list2.contains(temp)) {
                list1.add(temp);
            } else {
                list1.remove(Integer.valueOf(temp));
                list2.add(temp);
            }
            a = a / 10;
        }
        //实现Comparator,将优先队列从大到小排列
        PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;
            }
        });
        for(int i = 0;i<list1.size();i++){
            queue.add(list1.get(i));
        }
        for(int i = 0;i<list2.size();i++){
            queue.add(list2.get(i));
        }
        long res = 0;
        while (queue.size()!=0){
            res = res*10 + queue.poll();
        }
        return res;
    }

方法2:

public static long solution(long a){
        //利用桶计数方法,判断哪个值出现过
        int count[] = new int[10];
        //用来计数,如果前面出现了0-9的所有数,则提前结束循环
        List<Integer> list = new ArrayList<>();
        while (a!=0){
            int temp =(int) a%10;
            count[temp]++;
            //list里面存放没出现的值
            if(!list.contains(temp)){
                list.add(temp);
            }
            //判断是否提前结束循环
            if(list.size() == 10){
                break;
            }
            a = a / 10;
        }
        //结果的生成
        long res = 0;
        for(int i = count.length-1;i>=0;i--){
            if(count[i]!=0){
                res = res*10 + i;
            }
        }
        return res;
    }

仿LISP运算

1.题目描述

 LISP语言唯一的语法就是括号要配对。
 形如 (OP P1 P2 …),括号内元素由单个空格分割。
 其中第一个元素OP为操作符,后续元素均为其参数,参数个数取决于操作符类型
 注意:参数 P1, P2 也有可能是另外一个嵌套的 (OP P1 P2 …)
 当前OP类型为add/sub/mul/div(全小写),分别代表整数的加减乘除法。简单起见,所以OP参数个数为2
举例
  输入:(mul 3 -7)输出:-21
  输入:(add 1 2) 输出:3
  输入:(sub (mul 2 4) (div 9 3)) 输出 :5
  输入:(div 1 0) 输出:error
输入描述
  合法C字符串,字符串长度不超过512,用例保证了无语法错误
输出描述
  合法C字符串,字符包括’0’-‘9’及负号’-‘或者’error’

2.解题思路

按照题意模拟语法运算规则

3.代码

import java.util.Scanner;
import java.util.Stack;
public class Main_3 {
    public static void main(String[] args) {
        Scanner sr = new Scanner(System.in);
        String str = sr.nextLine();
        solution(str);
    }

    public static void solution(String str) {
        Stack<Integer> numStack = new Stack<>();
        Stack<String> operStack = new Stack<>();
        int mark = 0;
        int paramOne = 0;
        int paramTwo = 0;
        for(int i = 0;i<str.length();i++){
            char chas = str.charAt(i);
            if(chas == '('){
                //截取符号位
                operStack.push(str.substring(i+1,i+4));
                //这里为空格的索引位置
                i = i + 4;
                //符号位后第一个数字的索引坐标
                mark = i+1;
            }else if(chas == ')'){
                if(mark < i){
                    //所有数字的截取
                    numStack.push(Integer.valueOf(str.substring(mark,i)));
                    i++;
                    mark = i+1;
                }
                //得到一次()的对应,就进行一次计算
                paramOne = numStack.pop();
                paramTwo = numStack.pop();
                calc(numStack,operStack,paramOne,paramTwo);
            }else{
                //空格位将数字进行区分
                if(chas == ' '){
                    if(mark < i ){
                        numStack.push(Integer.valueOf(str.substring(mark,i)));
                        //下一个数字的索引为空格后面一位,故mark = i+1;
                        mark = i + 1;
                    }
                }
            }
        }
        //如果还有没计算完的,就进行再次计算
        while (!operStack.isEmpty()){
            paramTwo = numStack.pop();
            paramOne = numStack.pop();
            calc(numStack,operStack,paramOne,paramTwo);
        }
    }

    private static void calc(Stack<Integer> numStack, Stack<String> operStack, int paramOne, int paramTwo) {
        switch(operStack.pop()){
            case "add":
                numStack.push(paramOne + paramTwo);
                break;
            case "sub":
                numStack.push(paramOne - paramTwo);
                break;
            case "mul":
                numStack.push(paramOne * paramTwo);
                break;
            case "div":
                if(paramTwo == 0)
                    System.out.println("error");
                else
                    numStack.push(paramOne / paramTwo);
                break;
        }
    }
}

题目及代码整理自牛客技术资料
如有错误请指出!!

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值