左神_中级班_04

2.实现一个特殊栈,除了基本功能,还能返回栈中最小元素
解法:两个栈:stackData,stackMin

	public static class MyStack1 {
		private Stack<Integer> stackData;
		private Stack<Integer> stackMin;

		public MyStack1() {
			this.stackData = new Stack<Integer>();
			this.stackMin = new Stack<Integer>();
		}

		public void push(int newNum) {
			if (this.stackMin.isEmpty()) {
				this.stackMin.push(newNum);
			} else if (newNum <= this.getmin()) {
				this.stackMin.push(newNum);
			}
			this.stackData.push(newNum);
		}

		public int pop() {
			if (this.stackData.isEmpty()) {
				throw new RuntimeException("Your stack is empty.");
			}
			int value = this.stackData.pop();
			if (value == this.getmin()) {
				this.stackMin.pop();
			}
			return value;
		}

		public int getmin() {
			if (this.stackMin.isEmpty()) {
				throw new RuntimeException("Your stack is empty.");
			}
			return this.stackMin.peek();
		}
	}

3.1.用两个栈模拟一个队列

	public static class TwoStacksQueue {
		private Stack<Integer> stackPush;
		private Stack<Integer> stackPop;
		public TwoStacksQueue(){
			this.stackPush=new Stack<>();
			this.stackPop=new Stack<>();
		}
		public void push(int pushInt) {
			this.stackPush.add(pushInt);
		}

		public int poll() {
			if(this.stackPop.isEmpty()&&this.stackPush.isEmpty()){
				throw new RuntimeException("队列为空");
			}
			dao();
			return this.stackPop.pop();
		}

		public int peek() {
			if(this.stackPop.isEmpty()&&this.stackPush.isEmpty()){
				throw new RuntimeException("队列为空");
			}
			dao();
			return this.stackPop.peek();
		
		}
		public void dao(){
			if(this.stackPop.isEmpty()) {
				while (!this.stackPush.isEmpty()) {
					this.stackPop.push(this.stackPush.pop());
				}
			}
		}
	}

3.2.用两个队列模拟一个栈

	public static class TwoQueuesStack {
		private Queue<Integer> queue;
		private Queue<Integer> help;
		public TwoQueuesStack(){
			this.queue=new LinkedList<>();
			this.help=new LinkedList<>();
		}
		public void push(int pushInt) {
			queue.add(pushInt);
		}

		public int peek() {
			if(queue.isEmpty()){
				throw new RuntimeException("该栈中无元素");
			}
			while(queue.size()!=1){
				help.add(queue.poll());
			}
			int popInt=queue.peek();
			help.add(queue.poll());
			swap();
			return popInt;
		}

		public int poll() {
			if(queue.isEmpty()){
				throw new RuntimeException("该栈中无元素");
			}
			while(queue.size()!=1){
				help.add(queue.poll());
			}
			int popInt=queue.poll();
			swap();
			return popInt;
		}

		private void swap() {
			Queue<Integer> temp=this.queue;
			this.queue=this.help;
			this.help=temp;
		}
	}

4.给定二维数组,从左上角到右下角,每一步只能向下或者向右,沿途经过的数累加,返回最小路径和
(1)递归版本

	public static int getMinPath(int [][] arr){
		return process(arr,0,0);
	}

	private static int process(int[][] arr, int i, int j) {
		if(i==arr.length-1&&j==arr[0].length-1){
			return arr[i][j];
		}
		if(i==arr.length-1){
			return arr[i][j]+process(arr,i,j+1);
		}
		if(j==arr[0].length-1){
			return arr[i][j]+process(arr,i+1,j);
		}
		return arr[i][j]+Math.min(process(arr,i,j+1),process(arr,i+1,j));
	}

(2)dp

	public static int getMinPathDP(int [][] arr){
		int dp[][]=new int[arr.length][arr[0].length];
		int row=arr.length-1;
		int col=arr[0].length-1;
		dp[row][col]=arr[row][col];
		for(int i=row-1;i>=0;i--){
			dp[i][col]=arr[i][col]+dp[i+1][col];
		}
		for(int j=col-1;j>=0;j--){
			dp[row][j]=arr[row][j]+dp[row][j+1];
		}
		for(int i=row-1;i>=0;i--){
			for(int j=col-1;j>=0;j--){
				dp[i][j]=arr[i][j]+Math.min(dp[i][j+1],dp[i+1][j]);
			}
		}
		return dp[0][0];
	}

5.给定一个整形数组arr,已知其中所有的值都是非负的,将这个数组看作一个容器,请返回容器能装多少水
输入:[3,1,2,5,2,4] 输出:5
在这里插入图片描述

	public static int getWater5(int[] arr){
		if(arr==null||arr.length<3){
			return 0;
		}
		int all=0;//总的多少水
		int l=1;
		int r=arr.length-2;
		int maxl=arr[0];
		int maxr=arr[arr.length-1];
		while (l<=r){
			if(maxr<=maxl){
				all+=(maxr-arr[r])>0?(maxr-arr[r]):0;
				maxr=(maxr-arr[r])>0?maxr:arr[r];
				r--;
			}else{
				all+=(maxl-arr[l])>0?(maxl-arr[l]):0;
				maxl=(maxl-arr[l])>0?maxl:arr[l];
				l++;
			}
		}
		return all;
	}

(1)暴力,到每一个位置的时候求出左边的最大值与右边的最大值

	public static int max(int[] arr){
		int max=Integer.MIN_VALUE;
		int len=arr.length;
		for(int i=0;i<=len-2;i++){
			int maxLeft=Integer.MIN_VALUE;
			for(int j=0;j<=i;j++){
				if(arr[j]>=maxLeft){
					maxLeft=arr[j];
				}
			}
			int maxRight=Integer.MIN_VALUE;
			for(int m=i+1;m<=len-1;m++){
				if(arr[m]>=maxRight){
					maxRight=arr[m];
				}
			}
			max=Math.max(Math.abs(maxLeft-maxRight),max);
		}
		return max;
	}

(2)预处理数组:预先求出每个位置左边的最大值与右边的最大值

	public static int maxPreTreat(int[] arr){
		int len=arr.length;
		int [] left=new int[len];
		int maxLeft=Integer.MIN_VALUE;
		for(int i=0;i<=len-1;i++){
			if(i==0){
				left[i]=arr[i];
				maxLeft=arr[0];
			}else {
				left[i]=Math.max(maxLeft,arr[i]);
			}
		}
		int [] right=new int[len];
		int maxRight=Integer.MIN_VALUE;
		for(int i=len-1;i>=0;i--){
			if(i==len-1){
				right[i]=-1;
			}else{
				right[i]=maxRight=Math.max(maxRight,arr[i+1]);
			}
		}
		int max=Integer.MIN_VALUE;
		for(int i=0;i<=len-2;i++){
			max=Math.max(Math.abs(left[i]-right[i]),max);
		}
		return max;
	}

(3)最优化解法:求出数组最大值,两种情况:max在左侧和右侧

	public static int maxSimple(int[] arr){
		int max=Integer.MIN_VALUE;
		for(int i=0;i<arr.length;i++){
			max=Math.max(max,arr[i]);
		}
		int num=Math.max(Math.abs(max-arr[0]),Math.abs(max-arr[arr.length-1]));
		return num;
	}

7.题目:
如果一个字符串str,把字符串str前面任意的部分挪到后面形成的字符串叫做str的旋转词。
如str=“12345”,str的旋转词有"12345"、“23451”、“34512”、“45123”、“51234”。
给定两个字符串a和b,请判断a和b是否互为旋转词。
举例:
a=“cdab”,b=“abcd”,返回true;
a=“1ab2”,b=“ab12”,返回false;
a=“2ab1”,b=“ab12”,返回true。

	public static boolean isRotation1(String a, String b) {
		if (a==null||b==null||a.length()!=b.length()){
			return false;
		}
		String num=a+a;
		int is = num.indexOf(b);
		return is==-1?false:true;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值