剑指 Offer 29. 顺时针打印矩阵
剑指 Offer 31. 栈的压入、弹出序列
题目一:栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。
示例 1:
输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1] 输出:true 解释:我们可以按以下顺序执行: push(1), push(2), push(3), push(4), pop() -> 4, push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1示例 2:
输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2] 输出:false 解释:1 不能在 2 之前弹出。
解法一:以顺序双端队列为基础模拟栈的出入,首先遍历pushed,压入栈中;之后while一下,比较长度 非空 弹出和popped;之后弹出,最后比对长度是否一致
public boolean validateStackSequences(int[] pushed, int[] popped) {
Deque stack = new ArrayDeque<>();
int j = 0;
for (Integer elem : pushed) {
stack.push(elem);
while (j
解法二:也可以引入双指针,直接在pushed上模拟栈来达到O(1)的空间复杂度
public boolean validateStackSequences(int[] pushed, int[] popped) {
int top = -1, toDiscover = 0;
for(int e: popped) {
if (top != -1 && pushed[top] == e) {
top--;
continue;
}
while(toDiscover < pushed.length && pushed[toDiscover] != e) {
top++;
pushed[top] = pushed[toDiscover];
toDiscover++;
}
if(toDiscover == pushed.length) return false;
toDiscover++;
}
return true;
}
题目二:顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。 示例 1: 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5] 示例 2: 输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] 输出:[1,2,3,4,8,12,11,10,9,5,6,7]
解法一:看注释就行了,他就是模拟了一个矩阵,看着复杂,如果逻辑对很快就能出来
public int[] spiralOrder(int[][] matrix) {
if (matrix.length == 0) return new int[0];
// 当前打印上下左右四个边界,也就是当前所在的行、列
int m = matrix.length, n = matrix[0].length;
int[] res = new int[m * n];
int u = 0, d = matrix.length - 1, l = 0, r = matrix[0].length - 1;
int idx = 0;
while (true) {
// 在左上角时,从左往右
for (int i = l; i <= r; i++) {
res[idx++] = matrix[u][i]; // 打印完本行,上边界向下移动一位
}
if (++u > d) { // 上下边界相遇了,说明遍历结束
break;
}
// 在右上角时,从上往下
for (int i = u; i <= d; i++) {
res[idx++] = matrix[i][r]; // 打印完本列,右边界左移一位
}
if (--r < l) { // 左右边界相遇,说明遍历结束
break;
}
// 在右下角时,从右向左
for (int i = r; i >= l; i--) {
res[idx++] = matrix[d][i];
}// 打印完本行,下边界上移一位
if (--d < u) {
break; // 上下边界相遇,说明遍历结束
}
// 在左下角时,从下往上
for (int i = d; i >= u; i--) {
res[idx++] = matrix[i][l]; //打印完本列,左边界右移动一位
}
if (++l > r) { // 左右边界相遇,遍历结束
break;
}
}
return res;
}