1.求给定二叉树的最小深度。最小深度是指树的根结点到最近叶子结点的最短路径上结点的数量。
采用递归方法:
1.根为0,判断root==null,返回0
2.左节点和右节点都为0,判断root.left==null && root.right==null,返回1,此时1为根节点
3.左节点或右节点不为0,判断root.left==null || root.right==null,返回左右节点中较大值,再加上1根节点,最后返回节点中较小值。
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类
* @return int整型
*/
public int run (TreeNode root) {
// write code here
if(root==null){
return 0;
}else if(root.left==null && root.right==null){
return 1;
}else if(root.left==null || root.right==null){
return Math.max(run(root.left),run(root.right))+1;
}
return Math.min(run(root.left),run(root.right))+1;
}
}
2.计算逆波兰式(后缀表达式)的值,运算符仅包含"+","-","*"和"/",被操作数可能是整数或其他表达式
例如:
["20", "10", "+", "30", "*"] -> ((20 + 10) * 30) -> 900 ["40", "130", "50", "/", "+"] -> (40 + (130 / 50)) -> 42
思路:逆波兰式采用栈实现方式
若当前元素是数字就入栈,否则就是运算符,然后将该运算符前面两个数字进行相应操作,并将结果重新放入栈中,以便下次参与计算。
import java.util.Stack;
public class Solution {
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
int res = 0;
if(tokens == null || tokens.length <= 0){
return res;
}
if(tokens.length == 1){
res = Integer.valueOf(tokens[0]);
}
for(String str:tokens){
if(str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/")){
int v1 = stack.pop();
int v2 = stack.pop();
if(str.equals("+")){
res = v1+v2;
}else if(str.equals("-")){
res = v2-v1;
}else if(str.equals("*")){
res = v1*v2;
}else if(str.equals("/")){
res = v2/v1;
}
stack.push(res);
}else{
stack.push(Integer.valueOf(str));
}
}
return res;
}
}
3.对于给定的n个位于同一二维平面上的点,求最多能有多少个点位于同一直线上。
思路:点共线,确定斜率,斜率相同就共线。当两个点重合时,无法确定一条直线,但这也是共线的情况;
斜率不存在的情况,由于两个点(x1, y1)和(x2, y2)的斜率k表示为(y2 - y1) / (x2 - x1),那么当x1 = x2时斜率不存在,这种共线情况需要特殊处理。
double双精度会丢失准确性,采用最大公约数方法,以分数形式方式展现。
/*
*全部通过用例
* Definition for a point.
* class Point {
* int x;
* int y;
* Point() { x = 0; y = 0; }
* Point(int a, int b) { x = a; y = b; }
* }
*/
import java.util.*;
public class Solution {
public int maxPoints(Point[] points) {
int n = points.length;
if(n < 2) return n;
int ret = 0;
for(int i = 0; i < n; i++) {
// 分别统计与点i重合以及垂直的点的个数
int dup = 1, vtl = 0;
Map<Float, Integer> map = new HashMap<>();
Point a = points[i];
for(int j = 0; j < n; j++) {
if(i == j) continue;
Point b = points[j];
if(a.x == b.x) {
if(a.y == b.y) dup++;
else vtl++;
} else {
float k = (float)(a.y - b.y) / (a.x - b.x);
if(map.get(k) == null) map.put(k, 1);
else map.put(k, map.get(k) + 1);
}
}
int max = vtl;
for(float k: map.keySet()) {
max = Math.max(max, map.get(k));
}
ret = Math.max(ret, max + dup);
}
return ret;
}
}
import java.util.*;
public class Solution {
public int maxPoints (Point[] points) {
if(points==null){
return 0;
}
if(points.length<=2){
return points.length;
}
//key为每个数组除以最大公约数后的结果,比如[8,4],[4,2],[2,1]最后都变成[2,1]存储
Map<Integer,Map<Integer,Integer>> map=new HashMap<Integer,Map<Integer,Integer>>();
int result=0,max=0;
for(int i=0;i<points.length-1;i++){
//每次循环完毕要清空map,否则会把上次统计结果带到下一次循环来
map.clear();
//重复个数
int over=0;
for(int j=i+1;j<points.length;j++){
//计算出两者间隔
int x=points[j].x-points[i].x;
int y=points[j].y-points[i].y;
//重合+1
if(x==0 && y==0){
over++;
continue;
}
//计算分数形式的最大公约数
int gyd=generateGCD(x,y);
if(gyd!=0){
x=x/gyd;
y=y/gyd;
}
if(map.containsKey(x)){
if(map.get(x).containsKey(y)){
//次数
map.get(x).put(y,map.get(x).get(y)+1);
}else{
map.get(x).put(y,1);
}
}else{
Map<Integer,Integer> temp=new HashMap<Integer,Integer>();
temp.put(y,1);
map.put(x,temp);
}
//每次都将最大的放到max中,避免最后还要遍历判断map中最大次数
max=Math.max(max,map.get(x).get(y));
}
//最后的结果
result=Math.max(result,max+over);
}
return result;
}
public int generateGCD(int x,int y){
if(y==0){
return x;
}
return generateGCD(y,x%y);
}
}
4.在O(n log n)的时间内使用常数级空间复杂度对链表进行排序。