面试题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;
}
}