剑指offer[简单]

剑指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];
    }
}

基本就是这些,开始刷中等难度。
许愿秋招顺利找到工作!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值