剑指offer题解5

剑指offer题解5

18 顺时针打印矩阵

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

分析:依次遍历即可,注意各种条件


import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][]matrix) {
        int row=matrix.length,col=matrix[0].length;
        ArrayList<Integer> res=new ArrayList<>(row*col);
        //记录上下左右的界限
        int left=0,right=col-1,top=0,bottom=row-1;
        while(left<=right&&top<=bottom){
            for(int j=left;j<=right;j++){
                res.add(matrix[top][j]);
            }
            for(int j=top+1;j<=bottom;j++){
                res.add(matrix[j][right]);
            }
            //注意:bottom!=top,因为可能重复
            for(int j=right-1;j>=left&&bottom!=top;j--){
                res.add(matrix[bottom][j]);
            }
            for(int j=bottom-1;j>top&&left!=right;j--){
                res.add(matrix[j][left]);
            }
            left++;
            right--;
            top++;
            bottom--;
        }
        return res;
    }
}



import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][]matrix) {
        ArrayList<Integer> res =new ArrayList<>();
        if(matrix.length == 0 || matrix[0].length == 0){
            return res;
        }
        int row=matrix.length;
        int col=matrix[0].length;
        int num=Math.min(col,row)/2;
        //先搞定左右都能写入list的
        for (int i = 0; i <num ; i++) {
            for (int j = i; j <col-i ; j++) {
                res.add(matrix[i][j]);
            }
            for (int j = i; j <row-i-1 ; j++) {
                res.add(matrix[j+1][col-i-1]);
            }
            for (int j = i; j <col-i-1 ; j++) {
                res.add(matrix[row-1-i][col-j-2]);
            }
            for (int j = i; j <row-i-2 ; j++) {
                res.add(matrix[row-2-j][i]);
            }
        }
        //最后搞定单身的一行或者一列
        if((Math.min(col,row))%2!=0) {
            if (row < col) {
                for (int i = num; i <col-num ; i++) {
                    res.add(matrix[row/2][i]);
                }
            }else {
                for (int i = num; i <row-num ; i++) {
                    res.add(matrix[i][col/2]);
                }
            }
        }
        return res;
    }
}

19 包含min函数的栈

定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。

分析:使用两个栈,一个栈存所有的数,另一个栈从底到顶降序存储数据,因此获取min只需要O(1)的时间
删除时,只需要在必要时删除第二个栈中的数据即可

import java.util.Stack;

public class Solution {
    Stack<Integer> store=new Stack<>();
    Stack<Integer> desc=new Stack<>();
    public void push(int node) {
        store.push(node);
        //降序添加
        if(desc.isEmpty()||desc.peek()>=node){
            desc.push(node);
        }
    }
    
    public void pop() {
        //如果要删除的数在desc中,那么从desc中删除它
        if(store.peek()==desc.peek()){
            desc.pop();
        }
        store.pop();
    }
    
    public int top() {
        return store.peek();
    }
    
    public int min() {
        return desc.peek();
    }
}

20 栈的压入弹出序列

题目描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

分析:使用一个栈模拟压入弹出,一直压入直到弹出序列中出现与当前栈顶相同的数字,则一直弹出直到弹出序列中出现与当前栈顶不同的数字,最后栈判断是否为空


import java.util.*;

public class Solution {
    public boolean IsPopOrder(int [] pushA,int [] popA) {
      Stack<Integer> stack=new Stack<>();
        int j=0;
        for(int i=0;i<pushA.length;i++){
            stack.push(pushA[i]);
            //弹出
            while(!stack.isEmpty()&&stack.peek()==popA[j]){
                stack.pop();
                j++;
            }
        }
        return stack.isEmpty();
    }
}

21 从上往下打印二叉树

从上往下打印出二叉树的每个节点,同层节点从左至右打印。

分析:层次遍历,使用一个队列存储每一层的节点,然后依次遍历即可,也就是广度优先搜索

/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
        ArrayList<Integer> res=new ArrayList<>();
        LinkedList<TreeNode> queue=new LinkedList<>();
        if(root!=null){
            queue.add(root);
        }
        while(!queue.isEmpty()){
            int size=queue.size();
            for(int i=0;i<size;i++){
                //遍历同一层
                TreeNode curr=queue.get(0);
                res.add(curr.val);
                //添加下一层
                if(curr.left!=null){
                    queue.add(curr.left);
                }
                if(curr.right!=null){
                    queue.add(curr.right);
                }
                queue.remove(0);
            }
        }
        return res;
        
    }
}

猜你喜欢

转载自blog.csdn.net/gentlezuo/article/details/90580041