学习笔记10.16

剑指offer二刷

1.二维数组的查找

从上到下递增,从左到右递增,数组的每个L型序列都是个递增序列。

思路(1):从左下角开始判断,如果大于目标,则在上方;小于目标,则在下方。

思路(2):对每一个一维数组用二分查找。

2.替换空格

把给定字符串所有的空格换成%20。

如果从前往后替换的话,每替换一次,后面所有的字符都要整体后移,复杂度非常高。应该从后往前替换,先找出空格数目count,第一个空格后面的字符后移count*2,conut--,以此类推。

3.重建二叉树

已知先序遍历和中序遍历,重建二叉树。

根据先序遍历第一个元素为根,把中序遍历分成左右两个字树,同时先序遍历除了第一个元素外,也分成两个子树。然后子树在同上,递归运算,直到子树为空,返回。

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        int len = pre.size();
        if(len == 0) return NULL;
        vector<int> pre_left, pre_right, vin_left, vin_right;
        int pos;
        TreeNode* head = new TreeNode(pre[0]);
		for(int i = 0; i < len; i++)
            if(pre[0] == vin[i]){
                pos = i;
                break;
            }
        for(int i = 0; i < pos; i++){
            pre_left.push_back(pre[i+1]);
            vin_left.push_back(vin[i]);
        }
        for(int i = pos+1; i < len; i++){
            pre_right.push_back(pre[i]);
            vin_right.push_back(vin[i]);
        }
        head->left = reConstructBinaryTree(pre_left,vin_left);
        head->right = reConstructBinaryTree(pre_right,vin_right);
        return head;
    }
};

4.旋转数组的最小数字

把一个非递减数组的前面若干个数字搬移到后面,求最小数字。比如12345,变成34512。最小数字肯定为右侧序列第一个。

非递减就是递增和都相等。递增的情况里也有01111变成10111这种情况。

利用二分查找,如果num[mid]<num[right],说明mid和right都在右侧,令right=mid;如果num[mid]>num[right],说明mid在左侧,令left=mid+1。

因为当right和left相差仅一位时,mid为left,而且right肯定一直在右侧,所以此时有可能left和right都在右侧,left为最小元素,则判断后num[mid]<num[right]会left=mid+1,则right = left;

或者left在左侧,right为最小元素,则num[mid]>num[right],right=mid,即right=left;

所以这种情况left<right可作为循环进行条件。

还有一种都相等的情况。所以还要再加个条件,如果num[mid]=num[right],right=right-1;

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        int len = rotateArray.size();
        if(len == 0) return 0;
        int left = 0, right = len-1;
        while(left<right)
        {
            int mid = (left+right)/2;
            if(rotateArray[right]<rotateArray[mid]) left = mid+1;
            else if(rotateArray[right]>rotateArray[mid]) right = mid;
            else right--;
        }
        return rotateArray[left];
    }
};

5.斐波那契数列

class Solution {
public:
    int Fibonacci(int n) {
        if(n==0) return 0;
        if(n==1) return 1;
        int n1 = 0, n2 = 1;
        for(int i = 2; i <= n; i++)
        {
            n2 = n1+n2;
            n1 = n2-n1;
        }
        return n2;
    }
};

6.青蛙跳台阶

一个青蛙可以跳一个台阶,也可以跳两个台阶。跳n个台阶有多少种跳法。

青蛙最后一次跳一个台阶或者两个台阶跳到n个台阶,所以f(n)=f(n-1)+f(n-2)。所以就相当于斐波那契数列。

7.类似6

如果青蛙可以跳1到n任意个台阶,问跳n个台阶共多少种跳法。

如果青蛙要跳n个台阶:

第一次跳1个台阶,剩余n-1个台阶,方法有f(n-1)种;

第一次跳2个台阶,剩余n-2个台阶,方法有f(n-2)种;

以此类推,f(n)=f(n-1)+f(n-2)+.....+f(1)+1=2f(n-1)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值