算法营day3

牛客 菲波那切数列

题目描述
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1)。
n<=39
思路:
递归解法:效率低,重复计算和函数调用耗费多。
迭代解法
代码:

//这就是一份Dp的代码,迭代
class Solution {
    
    
public:
    int Fibonacci(int n) {
    
    //f(n-2) + f(n-1) = f(n)
        if(0 == n){
    
    
            return n;
        }
        int first = 1;
        int second = 1;
        int third = 1;//流氓啊,第一项和第二项不需要迭代。
        while(n > 2){
    
    
            third = first + second;
            first = second;//更新first
            second = third;//更新second
            --n;
        }
        return third;
    }
};
//这就是一份剪枝的代码
class Solution {
    
    
    unordered_map<int, int> filter;
public:
    int Fibonacci(int n) {
    
    //f(n-2) + f(n-1) = f(n)
        if(n ==0 || n == 1)
            return n;
        if(n == 2)
            return 1;
        int ppre = 0;
        if(filter.find(n-2) == filter.end()){
    
    
            ppre = Fibonacci(n-2);
            filter.insert({
    
    n-2,ppre});
        }
        else{
    
    
            ppre = filter[n-2];
        }
        int pre = 0;
        if(filter.find(n-1) == filter.end()){
    
    
            pre = Fibonacci(n-1);
            filter.insert({
    
    n-1,pre});
        }
        else{
    
    
            pre = filter[n-1];
        }
        
        return pre + ppre;
            
    }
};

牛客 跳台阶

题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
思路:
采用DP来进行处理,三步:

  • 定义状态
    f(n):青蛙跳上第n级台阶的总跳法
  • 状态转移方程
    f(n) = f(n-1) + f(n-2)
  • 设置初始值
    f(0) = 1,到0台阶的方法是1
    f(1) = 1
    f(2) = 2
    代码:
class Solution {
    
    
public:
    int jumpFloor(int number) {
    
    
        //f(n) = f(n-1) + f(n-2)
        //f(0) =1 ,f(1) =1,f(2)= 2
        vector<int> dp(number+1);
        dp[0] = 1;
        dp[1] = 1;
        dp[2] = 2;
        for(int i =2;i<=number;++i){
    
    
            dp[i] = dp[i-1] + dp[i-2];
        }
        return dp[number];
    }
};

优化空间:
本质就是:斐波那契数列
什么时候用Dp?

  • 找一批动态规划的题,练习3个步骤
  • 一般使用动归的时候,必定要使用数组(一维的或者二维的)

3+1(3个过程+一个数组)

牛客 矩形覆盖

题目描述
我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

比如n=3时,2*3的矩形块有3种覆盖方法:

代码:

//斐波那契数列变形,但是表现形式是不一样的
class Solution {
    
    
public:
    int rectCover(int number) {
    
    
        //f(n)总的方法数
        //f(n) = f(n-1)最后一次竖着放和f(n-1)本身方法数相同 + f(n-2)最后一次横着放
        //f(1) =1 ,f(2) = 2;
        int * dp = new int [number + 1];
        dp[1] =1;
        dp[2] = 2;
        for(int i = 3; i<=number;++i){
    
    
            dp[i] = dp[i-1] + dp[i-2];
        }
        int result = dp[number];
        delete dp;
        return result;
    }
};

牛客 二进制中的1的个数

题目描述
输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示

思路:
位运算处理
代码:

class Solution {
    
    
public:
     int  NumberOf1(int n) {
    
    
         int count = 0;
         while(n){
    
    
            n =  n & (n-1);
             ++count;
         }
         return count;//返回个数count
     }
};

牛客 链表中倒数第k个结点

题目描述
输入一个链表,输出该链表中倒数第k个结点。

思路:
有一些细节。
代码:

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
    
    
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
    
    
    if(pListHead == nullptr){
    
    
        return nullptr;
    }
    ListNode *front = pListHead;
    ListNode *rear = pListHead;
    while(k>0 && front){
    
    
        --k;
        front = front->next;
    }
    while(front){
    
    
        front = front->next;
        rear = rear->next;
    }
    return k > 0 ? nullptr : rear;
    }
};

力扣

从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。

例如:
给定二叉树: [3,9,20,null,null,15,7],

3

/
9 20
/
15 7

返回其层次遍历结果:

[
[3],
[9,20],
[15,7]
]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:
层序遍历,BFS,加上控制每一层的个数
代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
    
    
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
    
    
      if (root == nullptr) {
    
    
        return {
    
    };
      }
      vector<vector<int>> res;
      queue<TreeNode*> Q;
      TreeNode *temp;

      Q.push(root);
      while (!Q.empty()) {
    
    
        vector<int> T;
        int size = Q.size();    
        for(int i = 0; i < size; ++i) {
    
    //控制每层的个数   
          temp = Q.front();               
          Q.pop();
          T.push_back(temp->val);
          if (temp->left != nullptr) {
    
    
            Q.push(temp->left);
          }
          if (temp->right != nullptr) {
    
    
            Q.push(temp->right);
          }
        }
        res.push_back(T);
      }
      return res;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_35353824/article/details/107506768