刷题04——剑指offer07-13

面试题7:重建二叉树

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        if(pre == null || in == null || pre.length != in.length)
            return null;
        return constructCore(pre, 0, pre.length - 1, in, 0, in.length);
    }
    private TreeNode constructCore(int[] pre, int ps, int pe, int[] in, int is, int ie) {
        if(ps > pe) return null;
        int rootValue = pre[ps];
        int index = is;
        while(in[index] != rootValue) {
            index++;
        }
        TreeNode node = new TreeNode(rootValue);
        node.left = constructCore(pre, ps + 1, ps + index - is, 
                                  in, is, index - 1);
        node.right = constructCore(pre, ps + index - is + 1, pe,
                                  in, index + 1, ie);
        return node;
    }
}

面试题8:二叉树的下一节点

题目:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

/*
public class TreeLinkNode {
    int val;
    TreeLinkNode left = null;
    TreeLinkNode right = null;
    TreeLinkNode next = null;

    TreeLinkNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public TreeLinkNode GetNext(TreeLinkNode pNode)
    {
        if(pNode == null) return null;
        TreeLinkNode pNext = null;
        if(pNode.right != null) {
            pNext = pNode.right;
            while(pNext.left != null) {
                pNext = pNext.left;
            }
        } else if(pNode.next != null) {
            TreeLinkNode pCurrent = pNode;
            TreeLinkNode pParent = pNode.next;
            while(pParent != null && pParent.right == pCurrent) {
                pCurrent = pParent;
                pParent = pParent.next;
            }
            pNext = pParent;
        }
        return pNext;
    }
}

面试题9:用两个栈实现队列

题目:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

import java.util.Stack;

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
        stack1.push(node);
    }
    
    public int pop() {
        if(stack2.isEmpty()) {
            while(!stack1.isEmpty()) {
                stack2.push(stack1.pop());
            }
        }
        return stack2.pop();
    }
}

用队列实现栈:

class MyStack {
    LinkedList queue1; 
    LinkedList queue2;
    
    /** Initialize your data structure here. */
    public MyStack() {
        queue1 = new LinkedList();
        queue2 = new LinkedList(); 
    }
    
    /** Push element x onto stack. */
    public void push(int x) {
        queue1.add(x);
    }
    
    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        while(queue1.size() > 1) {
            queue2.add(queue1.remove());
        }
        int temp = (int)queue1.remove();
        LinkedList tempQueue = queue1;
        queue1 = queue2;
        queue2 = tempQueue;
        return temp;
    }
    
    /** Get the top element. */
    public int top() {
        while(queue1.size() > 1) {
            queue2.add(queue1.remove());
        }
        int temp = (int)queue1.remove();
        queue2.add(temp);
        LinkedList tempQueue = queue1;
        queue1 = queue2;
        queue2 = tempQueue;
        return temp;
    }
    
    /** Returns whether the stack is empty. */
    public boolean empty() {
        return queue1.isEmpty();
    }
}

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack obj = new MyStack();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.top();
 * boolean param_4 = obj.empty();
 */

面试题10:斐波那契数列

题目:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。

n<=39

递归版:

public class Solution {
    public int Fibonacci(int n) {
        if(n <= 0) return 0;
        if(n == 1) return 1;
        return Fibonacci(n - 1) + Fibonacci(n - 2);
    }
}

非递归版:

public class Solution {
    public int Fibonacci(int n) {
        if(n == 0) return 0;
        if(n == 1) return 1;
        int prePreNum = 0;
        int preNum = 1;
        int count = 0;
        for(int i = 2; i <= n; i++) {
            count = prePreNum + preNum;
            prePreNum = preNum;
            preNum = count;
        }
        return count;
    }
}

面试题11:旋转数组的最小数字

题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

import java.util.ArrayList;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
        if(array == null) return 0;
        int index1 = 0;
        int index2 = array.length - 1;
        int mid = 0;
        while(array[index1] >= array[index2]) {
            if(index2 - index1 == 1) {
                mid = index2;
                break;
            }
            mid = (index1 + index2) / 2;
            //顺序遍历
            if(array[index1] == array[index2] &&
               array[index1] == array[mid]) {
                int min = array[index1];
                for(int i = index1 + 1; i <= index2; i++) {
                    if(min > array[i]) {
                        min = array[i];
                    }
                }
                return min;
            }
            if(array[mid] >= array[index1]) {
                index1 = mid;
            } else if(array[mid] <= array[index2]) {
                index2 = mid;
            }
        }
        return array[mid];
    }
}

面试题12:矩阵中的路径

题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

public class Solution {
    public boolean hasPath(char[] matrix, int rows, int cols, char[] str)
    {
        if(matrix == null || rows < 1 || cols < 1 || str == null)
            return false;
        boolean[] visited = new boolean[rows * cols];
        for(int row = 0; row < rows; row++) {
            for(int col = 0; col < cols; col++) {
                if(hasPath(matrix, rows, cols, str, row, col,
                              visited, 0)) {
                    return true;
                }
            }
        }
        return false;
    }
    public boolean hasPath(char[] matrix, int rows, int cols, char[] str,
                          int row, int col, boolean[] visited, int pathLength) {
        if(pathLength == str.length) {
            return true;
        }
        boolean hasPath = false; 
        if(row >= 0 && row < rows && col >= 0 && col < cols && 
           !visited[row * cols + col] && 
           str[pathLength] == matrix[row * cols + col]) {
            visited[row * cols + col] = true;
            pathLength++;
            hasPath = hasPath(matrix, rows, cols, str, row + 1, col,
                              visited, pathLength) ||
                hasPath(matrix, rows, cols, str, row - 1, col,
                              visited, pathLength) ||
                hasPath(matrix, rows, cols, str, row, col + 1,
                              visited, pathLength) ||
                hasPath(matrix, rows, cols, str, row, col - 1,
                              visited, pathLength);
            if(!hasPath) {
                pathLength--;
                visited[row * cols + col] = false;
            }
        }
        return hasPath;
    }

}

面试题13、机器人的运动范围

题目:地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?

public class Solution {
    public int movingCount(int threshold, int rows, int cols) {
		if (threshold < 0)
			return 0;
		boolean[] visited = new boolean[rows * cols];
		int count = movingCountCore(threshold, rows, cols, 0, 0, visited);
		return count;
	}
 
	private int movingCountCore(int threshold, int rows, int cols, int row, int col, boolean[] visited) {
		int count = 0;
		if (check(threshold, rows, cols, row, col, visited)) {
			visited[row * cols + col] = true;
			count = 1 + movingCountCore(threshold, rows, cols, row + 1, col, visited)
					+ movingCountCore(threshold, rows, cols, row - 1, col, visited)
					+ movingCountCore(threshold, rows, cols, row, col + 1, visited)
					+ movingCountCore(threshold, rows, cols, row, col - 1, visited);
		}
		return count;
	}
	
	/*
	 * 判断数字是否满足条件
	 */
	private boolean check(int threshold, int rows, int cols, int row, int col, boolean[] visited) {
		if (row >= 0 && row < rows && col >= 0 && col < cols && visited[row * cols + col] == false
				&& getDigitSum(col) + getDigitSum(row) <= threshold)
			return true;
		return false;
	}
	/*
	 * 获得数字的数位之和
	 */
	private int getDigitSum(int col) {
		int sum=0;
		while(col!=0){
			sum+=col%10;
			col=col/10;
		}
		return sum;
	}
}

猜你喜欢

转载自blog.csdn.net/b515833/article/details/87872827