题目:你总共有 n 枚硬币,你须要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。java
给定一个数字 n,找出可造成完整阶梯行的总行数。n 是一个非负整数,而且在32位有符号整型的范围内。node
示例 1:算法
n = 5数组
硬币可排列成如下几行: ¤ ¤ ¤ ¤ ¤markdown
由于第三行不完整,因此返回2. 示例 2:函数
n = 8oop
硬币可排列成如下几行: ¤ ¤ ¤ ¤ ¤ ¤ ¤ ¤spa
思路一:rest
等差数列通项公式、求和公式code
已知等差数列的和Sn,首项a1=1,d=1,求n
public int arrangeCoins(int n) {
return (int) (-1 + Math.sqrt(1 + 8 * (long) n)) / 2;
}
复制代码
题目:实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。
示例 1:
输入:x = 2.00000, n = 10 输出:1024.00000 示例 2:
输入:x = 2.10000, n = 3 输出:9.26100 示例 3:
输入:x = 2.00000, n = -2 输出:0.25000 解释:2-2 = 1/22 = 1/4 = 0.25
public static double myPow(double x, int n) {
if(n==0) return 1;
if(n==1) return x;
if(n==-1) return 1/x;
double half=myPow(x,n/2);
double rest=myPow(x,n%2);
return half*half*rest;
}
复制代码
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例: 给定二叉树 [3,9,20,null,null,15,7],
3
复制代码
/
9 20 /
15 7 返回它的最大深度 3 。
public static int maxDepth(TreeNode root) {
if(root == null){
return 0;
}
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return (left > right?left:right)+1;
}
复制代码
题目: 请实现一个函数,用来判断一颗二叉树是否是对称的。注意,若是一个二叉树同此二叉树的镜像是一样的,定义其为对称的。
思路:首先根节点以及其左右子树,左子树的左子树和右子树的右子树相同,左子树的右子树和右子树的左子树相同便可,采用递归,另外非递归也可,采用栈或队列存取各级子树根节点。
方法一:
boolean isSymmetrical(TreeNode pRoot)
{
if(pRoot==null) return true;
return isSymmetrical(pRoot.left,pRoot.right);
}
private boolean isSymmetrical(TreeNode left, TreeNode right) {
if(left==null&&right==null) return true;
if(left==null||right==null) return false;
if(left.data==right.data)
return isSymmetrical(left.left, right.right)&&isSymmetrical(left.right, right.left);
return false;
}
复制代码
题目:给定一个二叉搜索树的根节点 root,返回树中任意两节点的差的最小值。
示例:
输入: root = [4,2,6,1,3,null,null] 输出: 1 解释: 注意,root是树节点对象(TreeNode object),而不是数组。
给定的树 [4,2,6,1,3,null,null] 可表示为下图:
4
/ \
2 6
/ \
1 3
复制代码
最小的差值是 1, 它是节点1和节点2的差值, 也是节点3和节点2的差值。
定义: 二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具备下列性质的二叉树: 若它的左子树不空,则左子树上全部结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上全部结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
class Solution {
Integer prev = null, ans = Integer.MAX_VALUE;
public int minDiffInBST(TreeNode root) {
test(root);
return ans;
}
public void test(TreeNode treeNode) {
if (treeNode == null) {
return;
}
test(treeNode.left);
if (prev != null) {
ans = Math.min(ans, treeNode.val - prev);
}
prev = treeNode.val;
test(treeNode.right);
}
}
复制代码
给定一个二叉树,返回全部从根节点到叶子节点的路径。
算法分析:
null
;故递归至上一个节点2搜索左子节点5,继续搜索判断5节点无左右子节点,故递归返回至1节点;public void sreachPaths(TreeNode root, List<String> paths, String path) {
if(root != null) {
path += Integer.toString(root.data);
if(root.left == null && root.right == null) {
paths.add(path);
}else {
path += "->";
sreachPaths(root.left, paths, path);
sreachPaths(root.right, paths, path);
}
}
}
复制代码
给定二叉搜索树的根结点 root,返回 L 和 R(含)之间的全部结点的值的和。
二叉搜索树保证具备惟一的值。
示例 1:
输入:root = [10,5,15,3,7,null,18], L = 7, R = 15 输出:32
示例 2: 输入:root = [10,5,15,3,7,13,18,1,null,6], L = 6, R = 10 输出:23
提示:
树中的结点数量最多为 10000 个。 最终的答案保证小于 2^31。
条件给出了根结点,从上往下遍历.可使用递归,来求解.重复的条件就是结点的左右子树,结束条件就是左右子树的值是否在L,R的范围内,返回结点在范围内的值的和
public int rangeSumBST(TreeNode root, int L, int R) {
if (root == null) {
return 0;
}
if (root.data < L) {
return rangeSumBST(root.right, L, R);
}
if (root.data > R) {
return rangeSumBST(root.left, L, R);
}
return root.data + rangeSumBST(root.left, L, R) + rangeSumBST(root.right, L, R);
}
复制代码
题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,知足 x 是 p、q 的祖先且 x 的深度尽量大(一个节点也能够是它本身的祖先)。”
例如,给定以下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]
示例 1: 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 输出: 3 解释: 节点 5 和节点 1 的最近公共祖先是节点 3。
示例 2: 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 输出: 5 解释: 节点 5 和节点 4 的最近公共祖先是节点 5。由于根据定义最近公共祖先节点能够为节点自己。
说明: 全部节点的值都是惟一的。 p、q 为不一样节点且均存在于给定的二叉树中。
思路:
一、在左、右子树中分别查找是否包含p或q,若是(两种状况:左子树包含p,右子树包含q/左子树包含q,右子树包含p),
那么此时的根节点就是最近公共祖先
二、若是左子树包含p和q,那么到root->left中查找,最近公共祖先在左子树里面
三、若是右子树包含p和q,那么到root->right中查找,最近公共祖先在右子树里面
四、注意:不可能left和right的返回值同时都是nullptr
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || p == root || q == root) {
return root;
}
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if (left!=null && right!=null) {
return root;
}
return left == null ? right : left;
}
复制代码
思路二(非递归):
public TreeNode lowestCommonAncestorII(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || p == root || q == root) {
return root;
}
List<TreeNode> pPath = findPath(root, p);
List<TreeNode> qPath = findPath(root, q);
TreeNode common = null;
for (int i=0, j=0; i<pPath.size() && j<qPath.size(); i++,j++) {
if (pPath.get(i) == qPath.get(j)) {
common = pPath.get(i);
}
}
return common;
}
private List<TreeNode> findPath(TreeNode root, TreeNode node) {
List<TreeNode> path = new ArrayList<>();
dfs(root, node, new ArrayList<>(), path);
return path;
}
private void dfs(TreeNode root, TreeNode node, List<TreeNode> tmp, List<TreeNode> path) {
if (root == null) {
return;
}
tmp.add(root);
if (root == node) {
path.addAll(new ArrayList<>(tmp));
}
dfs(root.left, node, tmp, path);
dfs(root.right, node, tmp, path);
tmp.remove(tmp.size()-1);
}
复制代码
一只青蛙一次能够跳上1级台阶,也能够跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(前后次序不一样算不一样的结果)。
考虑使用 斐波那契数列(递归)
方法一:使用递归的思想
public class Solution {
public int JumpFloor(int target) {
if(target<1)
return 0;
if(target==1)
return 1;
if(target==2)
return 2;
return JumpFloor(target-1)+ JumpFloor(target-2);
}
}
复制代码
方法二:使用迭代的思想
public class Solution {
public int JumpFloor(int target) {
int f1=1,f2=2;
while(--target>0){
f2=f2+f1;
f1=f2-f1;
}
return f1;
}
}
复制代码