剑指offer简单部分
斐波那契数列
f[0] = 0, f[1] = 1 ;
f[n] = f[n-1] + f[n-2]
四种解法添加链接描述
按照公式来算会超时
9/2 记忆化搜索
青蛙跳台阶
与数列思想相似
当前青蛙在第N阶,上一阶可能是N-1,也可能是N-2,因此问题转化成
=>方法数 = 跳上N-1的方法数 + 跳上N-2的方法数
public class Solution {
public int JumpFloor(int target) {
int temp[] = new int [target+1];
int i;
temp[0]=0;
temp[1]=1;
if(target > 1){
temp[2] = 2;
}
if(target>2){
for(i = 3 ; i < target+1 ; i++){
temp[i] = temp[i-1]+temp[i-2];
}
}
return temp[target];
}
}
变态跳台阶
青蛙每步可以任意跳跃
我最初的思想模仿跳台阶:
问题转化为
f[n] = f[n-1] + f[n-2] + … +f[1]
f[0] = 0,f[1] = 1
public class Solution {
public int JumpFloorII(int target) {
int temp[] = new int [target+1];
temp[1] = 1;
temp[0] = 0;
if(target > 1){
int i,j;
for(i = 2 ; i< target+1 ; i++){
for(j = 0; j < i ;j++){
temp[i]+=temp[j];
}
temp[i]++;
}
}
return temp[target];
}
}
牛客网上分享的思路:
f[n] = f[n-1] + f[n-2] + … +f[1]
f[n-1] = f[n-2] + … +f[1]
合并:f[n] = 2*f[n-1]
根据这个式子再进行记忆式搜索。还可以使用动态优化,但是临近秋招面试,一点都没准备测开的知识,只看了测试,先过一遍题目再说吧,接下来两天研究动态分析时再回顾
二叉树
和树有关的内容很久没看,这次直接回顾,基本都使用递归
进制转换-有关二进制的编程
不用加减乘除做加法
从来没见过这方面的题,因此没有思路,看了题解之后才明白,希望记住
二进制加法:
无进位和运算就是按位异或结果,进位就是与运算结果但是需要左移一位,因为进位影响下一位的运算。
所以s = a + b,其实就是无进位和+进位的结果。
算法步骤:
1.计算a和b的无进位和,和进位
2.如果进位不为0,则说明a+b的结果等于无进位和+进位,此时,把无进位和作为a,进位作为b,继续计算
3.如果进位等于0, 说明此时a+b的结果就等于无进位和,返回无进位和即可。
public class Solution {
public int Add(int num1,int num2) {
while (num2 != 0) {
int c = (num1 & num2) << 1;
num1 ^= num2;
num2 = c;
}
return num1;
}
}
旋转数组
理解错题意了,直接找的最小值,这样就忽略了给定条件。
正好复习二分法:
这种二分查找难就难在,arr[mid]跟谁比.
我们的目的是:当进行一次比较时,一定能够确定答案在mid的某一侧。一次比较为 arr[mid]跟谁比的问题。
一般的比较原则有:
1.如果有目标值target,那么直接让arr[mid] 和 target 比较即可。
2.如果没有目标值,一般可以考虑 端点
这里我们把target 看作是右端点,来进行分析,那就要分析以下三种情况,看是否可以达到上述的目标。
情况1,arr[mid] > target:4 5 6 1 2 3
arr[mid] 为 6, target为右端点 3, arr[mid] > target, 说明[first … mid] 都是 >= target 的,因为原始数组是非递减,所以可以确定答案为 [mid+1…last]区间,所以 first = mid + 1
情况2,arr[mid] < target:5 6 1 2 3 4
arr[mid] 为 1, target为右端点 4, arr[mid] < target, 说明答案肯定不在[mid+1…last],但是arr[mid] 有可能是答案,所以答案在[first, mid]区间,所以last = mid;
情况3,arr[mid] == target:
如果是 1 0 1 1 1, arr[mid] = target = 1, 显然答案在左边
如果是 1 1 1 0 1, arr[mid] = target = 1, 显然答案在右边
所以这种情况,不能确定答案在左边还是右边,那么就让last = last - 1;慢慢缩少区间,同时也不会错过答案。
public class Solution {
public int minNumberInRotateArray(int[] array) {
int i = 0, j = array.length - 1;
while (i < j) {
if (array[i] < array[j]) {
return array[i];
}
int mid = (i + j) >> 1;
if (array[mid] > array[i]) {
i = mid + 1;
} else if (array[mid] < array[j]) {
j = mid; // 如果是mid-1,则可能会错过最小值,因为找的就是最小值
} else i++; // 巧妙避免了offer书上说的坑点(1 0 1 1 1)
}
return array[i];
}
}
基本就是这些,开始刷中等难度。
许愿秋招顺利找到工作!!