21/03/05刷题记录Day14

232. 用栈实现队列

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列的支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false

说明:

你只能使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

思路

用栈实现队列,需要两个栈。
因为队列是先进先出,而栈是先进后出,所以要改变顺序,需要将其中一个栈来做进队操作,而另外一个栈做出队操作。数据顺序在两个栈中间进行改变

class MyQueue {

        Stack<Integer> s1;
		Stack<Integer> s2;
		
		 /** Initialize your data structure here. */
	    public MyQueue() {
	    	s1 = new Stack<>();
	    	s2 = new Stack<>();

	    }
	    
	    /** Push element x to the back of queue. */
	    public void push(int x) {进队--在s1入栈
	    	s1.push(x);
	    }
	    
	    /** Removes the element from in front of queue and returns that element. */
	    public int pop() {//出栈
	    	if(s2.isEmpty()) { --s2为空
	    		while(!s1.isEmpty()) {//s1不为空--将s1的元素全部压入s2.弹出s2栈顶
		    		s2.push(s1.pop());
		    	}
	    }
            if(!s2.isEmpty()){//s2不为空
                return s2.pop();
            }   
            return -1; 
	    }
	    
	    /** Get the front element. */
	    public int peek() {
            if(!s2.isEmpty()){
                return s2.peek();
            }
	    	if(!s1.isEmpty()) {
	    		while(!s1.isEmpty()) {
		    		s2.push(s1.pop());
		    	}
	    	}
	    	return s2.isEmpty() ? -1 : s2.peek();

	    }
	    
	    /** Returns whether the queue is empty. */
	    public boolean empty() {
	    	if(s1.isEmpty() && s2.isEmpty()) {
	    		return true;
	    	}
	    	return false;

	    }

}

在这里插入图片描述

122. 买卖股票的最佳时机 II

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

思路

1.这个题模拟股票交易最理想的状态–获得最大利润,那就是要在低点买入,高点卖出(画图很直观),最佳收益也就是差值为正的时候
2.所以求出每只股票与前一天的差值,为正即可
3.第一天的差值设为0.
4.综上,可以初探贪心策略:我们的目的是要求得整个买卖周期的最大收益。那么将整个买卖周期进行拆分,转化成为局部最大收益。每求解出一个局部最大收益,那么相对应的整体收益就会发生改变(贪心策略的特点)。而相对应的,动态规划求解的时候,局部解对整体解的正确结果没有影响,但是是一步步构成整体解的~

完整代码

public int maxProfit(int[] prices) {
        int n = prices.length;
		if(n == 0) {
			return 0;
		}
		int[] abs = new int[n];
		abs[0] = 0;
		for(int i = 1; i < n; i++) {
			abs[i] = prices[i] - prices[i - 1];
		}
		int res = 0;
		for(int i = 0; i < n; i++) {
			if(abs[i] > 0) {
				res += abs[i];
			}
		}
		return res;

    }

在这里插入图片描述

55. 跳跃游戏

给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标。

思路

用贪心算法的思想。
1.维护一个最远能够到达的坐标数组
2.用一个max变量储存已经遍历的元素所能够到达的最远位置。
3.如果当前坐标大于max,说明之前的坐标并不能跳过来。
4.如果当前坐标小于max,更新max,同时判断是否能够跳到终点

优化

这里的数组可以删掉,只要实时维护max变量就好了(但是作为贪心入门,还是建议不要跳过数组的维护)。

完整代码

int n = nums.length;
		int[] canJumps = new int[n];
		for(int i = 0; i < n - 1; i++) {
			canJumps[i] = nums[i] + i;
		}
		int max = 0;
		for(int i = 0; i < n - 1; i++) {
			if(i <= max) {
				max = Math.max(max, canJumps[i]);
				if(canJumps[i] >= n - 1) {
					return true;	
				}
			}			
		}
		return false;

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42180334/article/details/114383315