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.代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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.代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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;
}
}
}

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

文章目录
  1. 1. 数字反转相加
    1. 1.1. 1.题目描述
    2. 1.2. 2.解题思路
    3. 1.3. 3.代码
  2. 2. 消除重复数字
    1. 2.1. 1.题目描述
    2. 2.2. 2.解题思路
    3. 2.3. 3.代码
  3. 3. 仿LISP运算
    1. 3.1. 1.题目描述
    2. 3.2. 2.解题思路
    3. 3.3. 3.代码
| 139.6k