刷算法一直都是很痛苦,这里题主将牛客网算法题通过率由高到低的顺序进行排列,按由易到难的顺序进行刷题,希望能给大家带来信心!
题目描述
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
题解:
1.递归方法
public int TreeDepth(TreeNode root) {
return root == null ? 0 : 1 + Math.max(TreeDepth(root.left), TreeDepth(root.right));
}
2.非递归方法
采用层序遍历+队列存储的方法
思路:
链接:https://www.nowcoder.com/questionTerminal/435fb86331474282a3499955f0a41e8b?answerType=1&f=discussion
来源:牛客网
public int TreeDepth2(TreeNode root) {
if(root == null)
return 0;
Queue<TreeNode> queue = new LinkedList();
queue.add(root);
int high = 0;
int size;//用size控制high增长的次数和时机(同一层的元素没有完全退出队列的时候high不可以增加)
TreeNode node;
while(queue.size() != 0){
size = queue.size();//队列长度
while(size != 0){
node = queue.poll();
if(node.left != null)
queue.add(node.left);
if(node.right != null)
queue.add(node.right);
size--;//当size==0时说明同一层的元素遍历完成
}
high++;
}
return high;
}
题目描述
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
题解:
用到进制运算
两个二进制的相加结果是用一个异或门实现的;
两个二进制的进位结果是用一个与门来实现的。
执行加法 x ^ y
进位操作 ( x & y ) << 1
将两个结果循环操作直至进位为0,得到的加法结果则为最终结果
链接:https://www.nowcoder.com/questionTerminal/59ac416b4b944300b617d4f7f111b215?answerType=1&f=discussion
来源:牛客网
public class Solution {
public int Add(int num1,int num2) {
while(num2!=0){
//当进位为0时加法完成
int temp = num1^num2;//先查看非进位值
num2 = (num1&num2)<<1;//再查看进位值
num1 = temp;
}
return num1;
}
}
pblic void Mirror(TreeNode root) {
if(root == null){
return;
}
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
Mirror(root.left);
Mirror(root.right);
}
}
2.非递归方式
a.深度优先搜索,利用栈
链接:https://www.nowcoder.com/questionTerminal/564f4c26aa584921bc75623e48ca3011?answerType=1&f=discussion
来源:牛客网
import java.util.Stack;
public class Solution {
public void Mirror(TreeNode root) {
// 空树
if (root == null) {
return;
}
// 左右均为空
if (root.left == null && root.right == null) {
return;
}
// 用来遍历的栈
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(root);
TreeNode curNode;
TreeNode tempNode;
// 深度优先
while (!stack.isEmpty()) {
curNode = stack.pop();
if(curNode == null) {
continue;
}
if(curNode.left == null && curNode.right==null) {
continue;
}
// 交换
tempNode = curNode.left;
curNode.left = curNode.right;
curNode.right = tempNode;
stack.push(curNode.left);
stack.push(curNode.right);
}
}
}
b.广度优先,利用队列
import java.util.LinkedList;
import java.util.Queue;
public class Solution{
public void Mirror(TreeNode root) {
if(root == null) return;
Queue<TreeNode> nodes = new LinkedList<>();
TreeNode curr, temp;
nodes.offer(root);
while(!nodes.isEmpty()){
int len = nodes.size();
for(int i = 0; i < len; i++){
curr = nodes.poll();
temp = curr.left;
curr.left = curr.right;
curr.right = temp;
if(curr.left != null) nodes.offer(curr.left);
if(curr.right != null) nodes.offer(curr.right);
}
}
}
}
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
题解:
设 n 级台阶有f(n) 种跳法,根据最后一次跳台阶的数目可以分解为最后一次一级,则前面需要跳n-1 级,有f(n-1) 种跳法;最后一次跳两级,则前面需要跳n- 2 级,有f(n-2) 种跳法。以此类推 易知,
f(n)=f(n-1)+f(n-2)+……f(0)
f(n-1)=f(n-2)+……f(0)
两式相减得,
f(n)=2f(n-1) f(n)=2f(n−1)
链接:https://www.nowcoder.com/questionTerminal/22243d016f6b47f2a6928b4313c85387?f=discussion
来源:牛客网
public class Solution {
public int JumpFloorII(int target) {
if (target <= 0) {
return -1;
} else if (target == 1) {
return 1;
} else {
return 2 * JumpFloorII(target - 1);
}
}
}
题目描述
给你一根长度为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。
题解:
1.数学方法
4 : 2x2
5 : 2x3
6 : 3x3
7 : 2x2x3 或者4x3
8 : 2x3x3
9 : 3x3x3
10:2x2x3x3 或者4x3x3
可以看出剪出尽可能多的长度为3的片段,乘积最大。
public class Solution {
public int cutRope(int target) {
if(target==2)return 1;
else if(target==3)return 2;
else{
int x=target/3;
int y=target%3;
if(y==1){
return (int)Math.pow(3,x-1)*2*2;
}else{
return (int)Math.pow(3,x)*2;
}
}
}
}