1.如何仅用递归函数和栈操作逆序一个栈
一个栈依次压入1、2、3、4、5,那么从栈顶到栈底分别是5、4、3、2、1.将这个栈转置后,从栈顶到栈底为1、2、3、4、5,也就是实现栈中元素的逆序,但是只能用递归函数来实现,不用其他数据结构
说明:可以认为给定的字符串一定是正确的表达式,即不需要对str做公式有效性的检查;如果是负数,就需要用括号括起来,比如"4*(-3)",但如果负数作为公式的开头或括号部分的开头,则可以没有括号,比如"-3*4"和"(-3*4)"都是合法的;不考虑计算过程发生溢出的情况
一个栈依次压入1、2、3、4、5,那么从栈顶到栈底分别是5、4、3、2、1.将这个栈转置后,从栈顶到栈底为1、2、3、4、5,也就是实现栈中元素的逆序,但是只能用递归函数来实现,不用其他数据结构
首先,思考如何使用递归方法不使用辅助存储得到栈底元素:
public static int getAndRemoveLast(Stack<Integer> stack){
int result = stack.pop();
if(stack.isEmpty()){
return result;
}else{
int last = getAndRemoveLast(Stack);
stack.push(result);
return last;
}
}
接下来即水到渠成了:
public static void reverse(Stack<Integer> stack){
if(stack.isEmpty()){
return;
}
int i = getAndRemoveLast(stack);
reverse(stack);
stack.push;
}
说明:可以认为给定的字符串一定是正确的表达式,即不需要对str做公式有效性的检查;如果是负数,就需要用括号括起来,比如"4*(-3)",但如果负数作为公式的开头或括号部分的开头,则可以没有括号,比如"-3*4"和"(-3*4)"都是合法的;不考虑计算过程发生溢出的情况
public static int getNum(LinkedList<String> que){
int res = 0;
boolean add = true;
String cur = null;
int num = 0;
while(!que.isEmpty()){
cur = que.pollFirst();
if(cur.equals("+")){
add = true;
}else if(cur.equals("-")){
add = false;
}else{
num = Integer.valueOf(cur);
res += add ? num : (-num);
}
}
return res;
}
public static int getValue(String str){
return value(str.toCharArray(), 0)[0];
}
public static void addNum(LinkedList<String> que, int num){
if(!que.isEmpty()){
int cur = 0;
String top = que.pollLast();
if(top.equals("+") || top.equals("-")){
que.addLast(top);
}else{
cur = Integer.valueOf(que.pollLast);
num = top.equals("*") ? (cur * num) : (cur/num);
}
}
que.addLast(String.valueOf(num));
}
public static int[] value(char[] str, int i){
LinkedList<String> que = new LinkedList<String>();
int pre = 0;
int[] bra = null;
while(i < str.length && str[i] != ')'){
if(str[i] >= '0' && str[i] <= '9'){
pre = pre * 10 + str[i++] - '0';
}else if(str[i] != '('){
addNum(que, pre);
que.addLast(String.valueOf(str[i++]));
pre = 0;
}else{
//递归小括号
bra = value(str, i + 1);
pre = bra[0];
i = bra[i] + 1;
}
}
addNum(que,pre);
return new int[] {getNum(que), i};
}
3.生成窗口最大值数组
有一个整型数组arr和一个大小为w的窗口从数组的最左边滑到最右边,窗口每次向右滑一个位置。例如,数组为{4,3,5,4,3,3,6,7},窗口大小为3时:
[4 3 5] 4 3 3 6 7 窗口中最大值为5
4 [3 5 4] 3 3 6 7 窗口中最大值为5
4 3 [5 4 3] 3 6 7 窗口中最大值为5
4 3 5 [4 3 3] 6 7 窗口中最大值为4
4 3 5 4 [3 3 6] 7 窗口中最大值为6
4 3 5 4 3 [3 6 7] 窗口中最大值为7
如果数组长度为n,窗口大小为w,则一共产生n-w+1个窗口的最大值
请实现一个函数,输入:整型数组arr,窗口大小为w
输出:一个长度为n-w+1的数组res,res[i]表示每一种窗口状态下的最大值,以本例应返回结果是{5,5,5,4,6,7}
public static int[] getMaxWindow(int[] arr,int w){
if(arr == null || w < 1 || arr.length < w){
return null;
}
LinkedList<Integer> qmax = new LinkedList<Integer>();
int[] res = new int[arr.length - w + 1];
int index = 0;
for(int i = 0; i < arr.length; i++){
while(!qmax.isEmpty() && arr[qmax.peekLast()] <= arr[i]){
qmax.pollLast();
}
qmax.addLast(i);
if(qmax.peekFirst() == i - w){
qmax.pollFirst();
}
if(i >= w - i){
res[index++] = arr[qmax.peekFirst()];
}
}
return res;
}