努力经营当下,直至未来明朗!
文章目录
- 1. 青蛙跳台阶
- 2. 矩形覆盖
- 3. 二进制中1的个数
- 4. 链表中倒数第k个结点
普通小孩也要热爱生活!
1. 青蛙跳台阶
跳台阶
1)思路:如果青蛙在第n个台阶上,那么它要么来自n-1阶,要么来自n-2阶。(因为一次跳1 or 2级台阶)
2)动态规划dp问题:
① 定义状态; ② 编写状态方程; ③ 设置初始值
3)详细分析:
① f(n): 青蛙跳上第n级台阶的总跳法数 [定义状态]
②青 蛙跳到n级台阶的方法:要么直接从n-1跳,要么从n-2跳;但是n-2跳到n有两种方式:直接跳or从n-1跳,即:n-1到n-2的就被包含在n-1中
③ 所以:f(n) = f(n-1) + f(n-2) [转移方程]
④ f(0)=1; f(1)=1; f(2)=2; [设置初始值]
⑤ 注意:数组长度=目标台阶+1(从0开始的)
4)补充:一般使用动归,必定使用数组(一维or二维)
代码:
① 递归:
public class Solution {
public int jumpFloor(int target) {
// 使用递归
// 定义一个数组:数组长度!!
int[] dp = new int[target+1];
dp[0] = 1;
dp[1] = 1;
// 循环求跳法
for(int i=2; i<=target; i++) {
dp[i] = dp[i-1] + dp[i-2];
}
return dp[target];
}
}
② 迭代(fib)
public class Solution {
public int jumpFloor(int target) {
// 使用迭代(fib类似)
int first = 1;
int second = 1;
int third = 1;
// 循环求跳数
while(target >= 2) {
third = first + second;
first = second;
second = third;
target--;
}
return third;
}
}
2. 矩形覆盖
矩形覆盖
1)思路:
① 覆盖要么是横着覆盖,要么是竖着覆盖。
② n个小矩形覆盖:要么最后一个竖着放(到n-1),要么最后两个横着放(到n-2)。
2)代码:
public class Solution {
public int rectCover(int target) {
// 类似于fib
// f(n) = f(n-1) + f(n-2)
// 一定不要忘记这个,否则运行失败!
if(target < 2) {
return target;
}
// 注意数组长度!
int[] dp = new int[target+1];
// 初始化:
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
for(int i=3; i<=target; i++) {
dp[i] = dp[i-1] + dp[i-2];
}
return dp[target];
}
}
3. 二进制中1的个数
二进制中1的个数
1)二进制表示一定要体现出其数据类型的位数。如int,则二进制就需要32位来表示
2)思路:
① 按位与+左移/右移,但是不太推荐(如果0太多,无效检测就会增加);
② x&(x-1),直到为0,按位与的次数就是所求x中1的个数(推荐使用)
3)代码:
public class Solution {
public int NumberOf1(int n) {
int count = 0;
while(n != 0) {
n &= (n-1);
count++;
}
return count;
}
}
4. 链表中倒数第k个结点
链表中倒数第k个结点
1)思路:定义“前后指针”,前指针front先走k步,然后前后指针同时开始走,直到front走完遇到null,此时尾指针rear所在位置就是倒数第k个结点
2)代码:
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindKthToTail(ListNode head,int k) {
// 首先进行判断
if(head==null || k<0) {
return null;
}
// 定义前后指针
ListNode front = head;
ListNode rear = head;
// 开始进行走k步
while(k>0 && front!=null) {
front = front.next;
k--;
}
// 同时开始走,直到front==null
while(front != null) {
front = front.next;
rear = rear.next;
}
// 注意这里结束的判断条件!!
return (k>0)? null:rear;
}
}