编程之旅-Day16

52 篇文章 0 订阅
48 篇文章 0 订阅

目录

Day16-学习内容:

1.剑指Offer

面试题32:从上往下打印二叉树

面试题58:翻转字符

2.Leetcode

例1:跳跃游戏

例2:已知n,生成count-and-say 序列


1.剑指Offer

面试题32:从上往下打印二叉树

题目描述:从上往下打印出二叉树的每个节点,同层节点从左至右打印。

思路:使用队列进行广义优先遍历

代码:

class Solution {
public:
    vector<int> PrintFromTopToBottom(TreeNode* root) {
        vector<int> res;
        if(root==NULL){
             return res;
        }
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty()){
            TreeNode* pNode=q.front();
            res.push_back(pNode->val);
            if(pNode->left!=NULL){
                q.push(pNode->left);
            }
            if(pNode->right!=NULL){
                q.push(pNode->right);
            }
            q.pop();
        }
        return res;
    }
};

解析:<queue>操作

只能访问queue<T>容器适配器的第一个和最后一个元素。只能在容器的末尾添加新元素,只能从头部移除元素。FIFO(先进先出)

1.初始化

需要头文件<queue>

queue<int>que;

 

2.成员函数

C++队列Queue类成员函数如下:

back()返回最后一个元素

empty()如果队列空则返回真

front()返回第一个元素

pop()删除第一个元素

push()在末尾加入一个元素

size()返回队列中元素的个数

 

面试题58:翻转字符串

题目描述:牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

思路:先对整个字符反转一次,在对每个单词反转一次。

代码:

class Solution {
public:
    string ReverseSentence(string str) {
        std::reverse(str.begin(),str.end());
        
        int len=str.length();
        int begin=0;
        int end=0;
        while(begin<len){
            while(str[begin]==' '){
                begin++;   
            }
            end=begin;
            while(str[end]!=' '&&end<len){
                ++end;
            }
            std::reverse(str.begin()+begin,str.begin()+end);
            begin=end;  
        }
        return str;
    }
};

 

2.Leetcode

例1:跳跃游戏

题目描述:

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Determine if you are able to reach the last index.

For example:
A =[2,3,1,1,4], returntrue.

A =[3,2,1,0,4], returnfalse.

代码:

方法1:动态规划

思路:维护一个一维数组dp,其中dp[i]表示达到i位置时剩余的步数,那么难点就是推导状态转移方程。到达当前位置的剩余步数跟什么有关呢,其实是跟上一个位置的剩余步数和上一个位置的跳力有关,这里的跳力就是原数组中每个位置的数字,因为其代表了以当前位置为起点能到达的最远位置。所以当前位置的剩余步数(dp值)和当前位置的跳力中的较大那个数决定了当前能到的最远距离,而下一个位置的剩余步数(dp值)就等于当前的这个较大值减去1,因为需要花一个跳力到达下一个位置,所以我们就有状态转移方程了:dp[i] = max(dp[i - 1], nums[i - 1]) - 1,如果当某一个时刻dp数组的值为负了,说明无法抵达当前位置,则直接返回false,最后循环结束后直接返回true即可。

class Solution {
public:
    bool canJump(int A[], int n) {
        vector<int> dp(n,0);
        for(int i=1;i<n;i++){
            dp[i]=max(dp[i-1],A[i-1])-1;
            if(dp[i]<0) return false;
        }
        return true;
    }
};

方法2:贪心算法

思路:贪婪算法Greedy Algorithm,因为我们并不是很关心每一个位置上的剩余步数,我们只希望知道能否到达末尾,也就是说我们只对最远能到达的位置感兴趣,所以我们维护一个变量max,表示最远能到达的位置,初始化为0。遍历数组中每一个数字,如果当前坐标大于max或者max已经抵达最后一个位置则跳出循环,否则就更新max的值为其和i + nums[i]中的较大值,其中i + nums[i]表示当前位置能到达的最大位置。

class Solution
{
public:
    bool canJump(int A[], int n)
    {
       int max=0;            //max标记能跳到的最远处。
       for(int i=0;i<n&&max>=i;++i)    //max>=i表示此时能跳到i处,0<=i<n表
           if(i+A[i]>max)max=i+A[i];   //示扫描所有能到达的点,在改点处能跳到的最远处。
       return max>=n-1?true:false;     //如果最后跳的最远的结果大于等于n-1,那么满足
    }                                  //能跳到最后。
};

https://www.cnblogs.com/grandyang/p/4371526.html

 

例2:已知n,生成count-and-say 序列

题目描述:

The count-and-say sequence is the sequence of integers beginning as follows:
1, 11, 21, 1211, 111221, ...

1is read off as"one 1"or11.
11is read off as"two 1s"or21.
21is read off as"one 2, thenone 1"or1211.

Given an integer n, generate the n th sequence.

Note: The sequence of integers will be represented as a string.

思路:假设第一个是1,然后每一次前面生成的,n指读多少次。

n=1,就是1

n=2,就是读两次,结果为11

n=3,就是读3次,结果为21

n=4,就是读4次,结果为1211,

每一次读都是以前一次为基础

代码:

class Solution {
public:
    string countAndSay(int n) {
        if(n<=0) return "";
        string res="1";
        for(int i=1;i<n;i++){
            string t="";
            int count=1;
            for(int j=1;j<res.length();j++){
                if(res[j]==res[j-1]){
                    count++;
                }
                else{
                    t.push_back(count+'0');
                    t.push_back(res[j-1]);
                    count=1;
                }
            }
            t.push_back(count+'0');
            t.push_back(res[res.length()-1]);
            res=t;
        }
        return res;
    }
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值