有关递归的三道算法题总结

1.如何仅用递归函数和栈操作逆序一个栈
一个栈依次压入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;
}


2.给定一个字符串str,str表示一个表达式,其中只可能有整数、加减乘除符号和左右括号,返回公式的计算结果,例如:str = "48*((70-65)-43)+8*1",返回-1816;str="3+1*4",返回7;str="3+(1*4)",返回7
说明:可以认为给定的字符串一定是正确的表达式,即不需要对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;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值