ArrayDeque和LinkedList类都实现了Deque接口,提供了双端队列。
// 队列:LinkedList类
LinkedList<T> queue = new LinkedList<>();
// 入队
add(Object o);
// 出队
remove();
// 栈:ArrayDeque类
Deque<T> stack = new ArrayDeque<>();
// 入栈
addFirst(e);
// 出栈
removeFirst();
// 查看栈顶元素
peekFirst();
20 Valid Parentheses Easy
Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. An input string is valid if:
Open brackets must be closed by the same type of brackets.
Open brackets must be closed in the correct order.
Note that an empty string is also considered valid.
Example 1:
Input: "()"
Output: true
Example 2:
Input: "()[]{}"
Output: true
Example 3:
Input: "(]"
Output: false
Example 4:
Input: "([)]"
Output: false
Example 5:
Input: "{[]}"
Output: true
思路:一次遍历string中的char,如果是左括号就入栈;如果是右括号,检查栈如果为空,证明不能匹配,如果栈不空,弹出top,与当前扫描的括号检查是否匹配。 全部字符都检查完了以后,判断栈是否为空,空则正确都匹配,不空则证明有没匹配的。
class Solution {
public boolean isValid(String s) {
Deque<Character> stack = new ArrayDeque<>();
for(int i=0; i<s.length(); i++) {
char ch = s.charAt(i);
if(ch=='(' || ch=='{' || ch=='[') {
stack.addFirst(ch);
} else {
if(stack.size()==0) {
return false;
}
char top = stack.removeFirst();
if(!isPaired(top,ch)) {
return false;
}
}
}
return stack.size()==0;
}
private boolean isPaired(char ch1, char ch2) {
if(ch1=='(' && ch2==')') {
return true;
} else if(ch1=='{' && ch2=='}') {
return true;
} else if(ch1=='[' && ch2==']') {
return true;
} else {
return false;
}
}
}
32 Longest Valid Parentheses Hard
Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.
Example 1:
Input: "(()"
Output: 2
Explanation: The longest valid parentheses substring is "()"
Example 2:
Input: ")()())"
Output: 4
Explanation: The longest valid parentheses substring is "()()"
题意:字符串中只有圆括号'(' ')',求最长匹配括号子串的长度。
思路:需要维护一个合法开始的起点start,用于计算当前合法序列的长度。
需要考虑的例子:()(()
class Solution {
public int longestValidParentheses(String s) {
Deque<Integer> stack = new ArrayDeque<>();
int maxLength = 0;
int start = 0;
for(int i=0; i<s.length(); i++) {
char ch = s.charAt(i);
if(ch=='(') {
// 由于本题只有圆括号,所以没有必要将括号入栈
// 只需要记录入栈的左括号的下标,用于计算合法序列的长度
stack.addFirst(i);
} else {
if(stack.size()==0) {
// 只有)来栈中没有(与之匹配时修改start
start = i+1;
continue;
}
stack.removeFirst();
if(stack.size()==0) {
maxLength=Math.max(i-start+1, maxLength);
} else {
maxLength=Math.max(i-stack.peek(),maxLength);
}
}
}
return maxLength;
}
}
84 Largest Rectangle in Histogram Hard
Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].
The largest rectangle is shown in the shaded area, which has area = 10 unit.
Example:
Input: [2,1,5,6,2,3]
Output: 10
暴力方法:遍历所有[i, j],并在过程中找出中间最矮的bar,得出从i到j的矩形面积。,超时。
优雅的方法:用栈 (附图解)
class Solution {
public int largestRectangleArea(int[] heights) {
int maxArea = 0;
int[] h = new int[heights.length+1];
h = Arrays.copyOf(heights, heights.length+1);
Deque<Integer> stack = new ArrayDeque<>();
int i=0;
while(i<h.length) {
if(stack.size()==0 || h[i]>=h[stack.peekFirst()]) {
// 只有入栈后i向后移动
stack.addFirst(i++);
} else {
int bar = h[stack.removeFirst()];
maxArea = Math.max(maxArea, stack.size()==0 ? bar*i : bar*(i-stack.peekFirst()-1));
}
}
return maxArea;
}
}
71 Simplify Path Medium
Given an absolute path for a file (Unix-style), simplify it.
For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
Corner Cases:
Did you consider the case where path = "/../"?
In this case, you should return "/".
Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/".
In this case, you should ignore redundant slashes and return "/home/foo".
题意:Linux下的文件目录 . 代表此层目录,.. 代表上一层目录。3个及以上的点照搬。
思路:使用双向队列
class Solution {
public String simplifyPath(String path) {
Deque<String> stack = new ArrayDeque<>();
// 先取/分隔出的内容放入数组
String[] strings = path.split("/");
for(String str:strings) {
if(str.equals(".") || str.equals("")) {
continue;
} else if(str.equals("..")) {
if(stack.size()!=0) {
stack.removeLast();
}
} else {
stack.addLast(str);
}
}
if(stack.size()==0) {
return "/";
}
StringBuilder builder = new StringBuilder();
while(stack.size()!=0) {
builder.append("/"+stack.removeFirst());
}
return builder.toString();
}
}