61.请实现两个函数,分别用来序列化和反序列化二叉树
public class Solution {
String Serialize(TreeNode root) {
if(root == null) return "#";
return root.val + "," + Serialize(root.left) + "," + Serialize(root.right);
}
int index = -1;
TreeNode Deserialize(String str) {
if(str == null) return null;
String[] s = str.split(",");
return Deserialize(s);
}
TreeNode Deserialize(String[] str) {
index++;
if(!str[index].equals("#")){
TreeNode node = new TreeNode(Integer.parseInt(str[index]));
node.left = Deserialize(str);
node.right = Deserialize(str);
return node;
}
return null;
}
}
62.给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。
import java.util.*;
public class Solution {
List<TreeNode> list = new ArrayList<>();
TreeNode KthNode(TreeNode pRoot, int k){
sort(pRoot);
if(k <= 0 || k > list.size()) return null;
return list.get(k-1);
}
void sort(TreeNode root){
if(root != null){
sort(root.left);
list.add(root);
sort(root.right);
}
}
}
63.如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
import java.util.*;
public class Solution {
PriorityQueue<Integer> high = new PriorityQueue<>();//后半部分小根堆,从小到大
PriorityQueue<Integer> low = new PriorityQueue<>(new Comparator<Integer>(){
public int compare(Integer o1,Integer o2){
return o2 - o1;
}
});//前半部分大根堆,从大到小
public void Insert(Integer num) {
low.offer(num);
high.offer(low.poll());
if(high.size()>low.size()){
low.offer(high.poll());
}
}
public Double GetMedian() {
return low.size() == high.size() ?
(low.peek() + high.peek())/2.0 : low.peek()*1.0;
}
}
64.给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
import java.util.*;
public class Solution {
public ArrayList<Integer> maxInWindows(int [] num, int size){
ArrayList<Integer> list = new ArrayList<>();
if(size <= 0 || size > num.length) return list;
PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>(){
public int compare(Integer o1,Integer o2){
return o2 - o1;
}
});
for(int i = 0; i < size ; i++){
queue.offer(num[i]);
}
list.add(queue.peek());
for(int i = size; i < num.length; i++){
queue.remove(num[i - size]);
queue.offer(num[i]);
list.add(queue.peek());
}
return list;
}
}
65.题目描述请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如
|a b c e|
|s f c s |
|a d e e|
矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
public class Solution {
int[][] visit ;
public boolean hasPath(char[] matrix, int rows, int cols, char[] str){
visit = new int[rows][cols];
char[][] arr = new char[rows][cols];
for(int i = 0;i < rows ;i++){
for(int j = 0;j < cols;j++){
arr[i][j] = matrix[i * cols + j];
}
}
for(int i = 0;i < rows ;i++){
for(int j = 0;j < cols;j++){
if(find(arr,str,rows,cols,i,j,0)){
return true;
}
}
}
return false;
}
public boolean find(char[][] arr,char[] str,int rows, int cols,int h,int l,int index){
if(index >= str.length) return true;
if( h < 0 || h >= rows || l < 0 || l >= cols ||
arr[h][l] != str[index] || visit[h][l] == 1){
return false;
}
visit[h][l] = 1;
boolean isPath = find(arr,str,rows,cols,h-1,l,index+1)||
find(arr,str,rows,cols,h+1,l,index+1)||
find(arr,str,rows,cols,h,l-1,index+1)||
find(arr,str,rows,cols,h,l+1,index+1);
visit[h][l] = 0;
return isPath;
}
}
66.地上有一个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;
}
int[][] visit = new int[rows][cols];
return move(threshold,rows,cols,0,0,visit) + 1;
}
private final int[] dx = {-1,1,0,0};
private final int[] dy = {0,0,-1,1};
public int sum(int x){
int ans = 0;
while(x > 0){
ans += x%10;
x /= 10;
}
return ans;
}
public int move(int threshold, int rows, int cols,int h,int l,int[][] visit){
visit[h][l] = 1;
int count = 0;
for(int i = 0;i < 4;i++){
int x = h + dx[i];
int y = l + dy[i];
if(x >= 0 && x < rows && y >= 0 && y < cols &&
visit[x][y] != 1 && sum(x) + sum(y) <= threshold){
count += move(threshold,rows,cols,x,y,visit) + 1 ;
}
}
return count;
}
}
67.给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],…,k[m]。请问k[0]xk[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
public class Solution {
public int cutRope(int target) {
if(target <= 3){
return target - 1;
}
int i = 1;
while(target > 4){
i *= 3;
target -= 3;
}
return target * i;
}
}