携程2021.3.4 研发笔试
1.表达式解析求解,需要利用栈进行处理
public class expressionStack {
public static void main(String[] args) {
String str = "(- (- (* 4 5 ) 4 6 ) 9)";
System.out.println(resolveString(str));
}
private static int resolveString(String str) {
char[] strArr = str.toCharArray();
Stack<String> stack = new Stack<>();
int i = 0;
//每次最多添加一个字符
while (i < strArr.length) {
if (strArr[i] == ' ') {
i++;
continue;
//处理当前括号内运算
} else if (strArr[i] == ')') {
//因为运算符总是跟在左括号前面,需要使用临时栈来放到临时栈顶
Stack<String> tmpStack = new Stack<>();
String tmp = stack.pop();
while (!"(".equals(tmp)) {
tmpStack.push(tmp);
tmp = stack.pop();
}
tmp = "";
i++;
String operator = tmpStack.pop();
int ans = 0;
switch (operator) {
case "+":
while (!tmpStack.isEmpty()) {
ans += Integer.parseInt(tmpStack.pop());
}
break;
case "-":
ans = Integer.valueOf(tmpStack.pop());
while (!tmpStack.isEmpty()) {
ans -= Integer.parseInt(tmpStack.pop());
}
break;
case "*":
ans = Integer.valueOf(tmpStack.pop());
while (!tmpStack.isEmpty()) {
ans *= Integer.parseInt(tmpStack.pop());
}
break;
}
stack.push(String.valueOf(ans));//计算后的数字添加到栈里
continue;//处理完一个括号内运算后进行下一次循环
}
if (strArr[i] == '(' || strArr[i] == '+' || strArr[i] == '-' || strArr[i] == '*') {
stack.push(String.valueOf(strArr[i++]));
} else {
stack.push(String.valueOf(strArr[i++]));//数字
}
}
return Integer.valueOf(stack.pop());
}
}
2.新春红包礼盒
找到自己能分得红包的最大值,即意味着之前拿到红包的人额度都比自己大,并且尽量不要让他们拿到的额度过大,否则自己分到的就更少。处理逻辑是在treeset中添加n+1个元素,得到最小值,即为自己能拿到的最大值,利用了treeset可以获得头和尾元素的特性,但要处理treeset自带的根据key值去重问题。具体步骤是:
- 添加n+1个元素到treeset中
- 超出大小的元素需要与当前set倒数第二个元素比较,大于则合并set中倒数两个元素,并添加当前元素
- 小于,则合并当前元素+倒数第一个元素,
public class PackageDivided {
public static void main(String[] args) {
int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
int n = 5;
System.out.println(Arrays.toString(dividePakage(arr, n)));
}
//数组最后一项即为
private static int[] dividePakage(int[] arr, int n) {
TreeSet<Node> set = new TreeSet<>((o1, o2) -> {
if (o2.val != o1.val) {
return o2.val - o1.val;
}
return o2.startIndex - o1.startIndex;
});
for (int i = arr.length - 1; i >= 0; i--) {
if (set.size() <= n) {
set.add(new Node(i, arr[i]));
} else {
Node tail = set.pollLast();
//arr[i]比set倒数第二个元素大,则倒数两项相加合为一项,并添加arr[i]项
if (arr[i] > set.last().val) {
set.add(new Node(set.last().startIndex, set.last().val + tail.val));
set.pollLast();
set.add(new Node(i, arr[i]));
} else {
//arr[i]比set倒数第二个元素小,则最后一项tail.val加arr[i]和最小
set.add(new Node(tail.startIndex, tail.val + arr[i]));
}
}
}
int[] res = new int[n + 1];
int index = 0;
Iterator<Node> iterator = set.iterator();
while (iterator.hasNext()) {
res[index++] = iterator.next().val;
}
return res;
}
//创建Node避免treeset只根据数组值去重
static class Node {
int startIndex;
int val;
public Node(int index, int val) {
this.startIndex = index;
this.val = val;
}
}
}
查看19道真题和解析