进击的墩墩:Round 1

开始刷题:

一、替换空格

题目描述:请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。(图片来自https://www.cnblogs.com/edisonchou/p/4738106.html

解法一:倒序插入

思路:

1.先求出空格数black

2.然后求出替换过后的新长度=原字符串长度length + black*2

3.然后定义两个指针,p1指向原来字符串末尾,p2指向新长度的末尾

4.开始循环,循环条件:p2 > p1,

       当遇到p1==空格,从后向前替换 顺序为 ‘0’ ‘2’ ‘%’;

       当不是空格,将当前p1所指向的值移动到p2所指向的位置,然后两个指针同时--;

这个之前剑指offer做过,剑指版代码:

class Solution {
public:
    void replaceSpace(char *str,int length) {
        int black = 0;
         
        for(int i = 0;i < length;i++){
            if(str[i] == ' ')
                black++;   
        }    
         
        int newIndex = length + 2 * black;
        char *index = str + length;
        while(index >= str){
            if(*index == ' '){
                str[newIndex--] = '0';
                str[newIndex--] = '2';
                str[newIndex--] = '%';
            }
            else{
                str[newIndex--] = *index;
            }
            index--;
        }
    }
};

解法二:利用string的特性

发现的大佬的代码,简洁!明了!空间复杂度和时间复杂度也比第一种解法好。


分析:

1.先将char *转为string,

2.然后处理完成后再转为char *,但不是以返回值的形式,还要利用好原来的空间,用strcpy实现之。

3.处理过程循环查找利用find函数,每次找到就替换,且把每次的找到的结果当成下一次的参数,避免重复从头查找。

class Solution {
public:
    void replaceSpace(char *str,int length) {
        string s(str);
        int i=0;
        while((i=s.find(' ',i))>-1){//返回字符ch在字符串中第一次出现的位置(从i开始查找)
            s.erase(i,1);//删除从i索引开始的1个字符, 返回*this.
            s.insert(i,"%20");//在i的位置插入“%20”
             
        }
        auto ret=s.c_str();
        strcpy(str,ret);//c_str()函数返回一个指向正规C字符串的指针, 内容与本字符串相同.
    }
};

大佬对string函数非常熟悉,这个代码的空间复杂度和时间复杂度,都比上面那种倒着写的高

今天学到了string的用法

添加文本(append) 

语法:

  basic_string &append( const basic_string &str );
  basic_string &append( const char *str );
  basic_string &append( const basic_string &str, size_type index, size_type len );
  basic_string &append( const char *str, size_type num );
  basic_string &append( size_type num, char ch );
  basic_string &append( input_iterator start, input_iterator end );

append() 函数可以完成以下工作:

查找(find)

  • 在字符串的末尾添加str,
  • 在字符串的末尾添加str的子串,子串以index索引开始,长度为len
  • 在字符串的末尾添加str中的num个字符,
  • 在字符串的末尾添加num个字符ch,
  • 在字符串的末尾添加以迭代器start和end表示的字符序列.

语法:

  size_type find( const basic_string &str, size_type index );
  size_type find( const char *str, size_type index );
  size_type find( const char *str, size_type index, size_type length );
  size_type find( char ch, size_type index );

find()函数:

  • 返回str在字符串中第一次出现的位置(从index开始查找)如果没找到则返回string::npos,
  • 返回str在字符串中第一次出现的位置(从index开始查找,长度为length)。如果没找到就返回string::npos,
  • 返回字符ch在字符串中第一次出现的位置(从index开始查找)。如果没找到就返回string::npos

 

删除(erase)

语法:

  iterator erase( iterator pos );
  iterator erase( iterator start, iterator end );
  basic_string &erase( size_type index = 0, size_type num = npos );

erase()函数可以:

  • 删除pos指向的字符, 返回指向下一个字符的迭代器,
  • 删除从start到end的所有字符, 返回一个迭代器,指向被删除的最后一个字符的下一个位置
  • 删除从index索引开始的num个字符, 返回*this.

 

c_str语法:

  •   const char *c_str();
    

    c_str()函数返回一个指向正规C字符串的指针, 内容与本字符串相同.

 

插入(insert)

语法:

  iterator insert( iterator i, const char &ch );
  basic_string &insert( size_type index, const basic_string &str );
  basic_string &insert( size_type index, const char *str );
  basic_string &insert( size_type index1, const basic_string &str, size_type index2, size_type num );
  basic_string &insert( size_type index, const char *str, size_type num );
  basic_string &insert( size_type index, size_type num, char ch );
  void insert( iterator i, size_type num, const char &ch );
  void insert( iterator i, iterator start, iterator end );

insert()函数的功能非常多:

  • 在迭代器i表示的位置前面插入一个字符ch,
  • 在字符串的位置index插入字符串str,
  • 在字符串的位置index插入字符串str的子串(从index2开始,长num个字符),
  • 在字符串的位置index插入字符串str的num个字符,
  • 在字符串的位置index插入num个字符ch的拷贝,
  • 在迭代器i表示的位置前面插入num个字符ch的拷贝,
  • 在迭代器i表示的位置前面插入一段字符,从start开始,以end结束

 

 二、网易实习生招聘编程题-----牛牛找工作

 

题目描述

为了找到自己满意的工作,牛牛收集了每种工作的难度和报酬。牛牛选工作的标准是在难度不超过自身能力值的情况下,牛牛选择报酬最高的工作。在牛牛选定了自己的工作后,牛牛的小伙伴们来找牛牛帮忙选工作,牛牛依然使用自己的标准来帮助小伙伴们。牛牛的小伙伴太多了,于是他只好把这个任务交给了你。

输入描述:

每个输入包含一个测试用例。
每个测试用例的第一行包含两个正整数,分别表示工作的数量N(N<=100000)和小伙伴的数量M(M<=100000)。
接下来的N行每行包含两个正整数,分别表示该项工作的难度Di(Di<=1000000000)和报酬Pi(Pi<=1000000000)。
接下来的一行包含M个正整数,分别表示M个小伙伴的能力值Ai(Ai<=1000000000)。
保证不存在两项工作的报酬相同。

输出描述:

对于每个小伙伴,在单独的一行输出一个正整数表示他能得到的最高报酬。一个工作可以被多个人选择。

示例1

输入

3 3 
1 100 
10 1000 
1000000000 1001 
9 10 1000000000

输出

100 
1000 
1001

思路1:
​​​​​​1、用vector<vetcor<int>> work模拟二维数组保存n个工作的难度和报酬;

      //(或者定义一个结构体struct Node,里面保存: 工作难度,报酬)
2、将m个牛牛小伙伴按能力从小到大排序,如果难度相等的时候按照他们的酬劳进行排序;
3、然后按照工作难度进行排序,如果难度相等的时候按照他们的酬劳进行排序;
4、循环判断m个小伙伴,每次嵌套循环判断,如果:当前小伙伴能力 >= 当前工作的难度 && 当前工作的难度的报酬 >= 之前的报酬最大值;
5、更新最大值报酬;

第一次代码:然后这个思路的代码我没实现出来(菜是原罪!),下附上初始思路代码。程序崩溃,vetor越界!

#include <iostream>
#include <vector>
using namespace std;
 
int main()
{
    int N,M; 
    int ability,money;
    int level; 
    vector<vector<int>> work;
    vector<int> lev;
    cin >> N >> M;
    for(int i = 0; i < N; ++i){//保存n个工作的难度和报酬
        cin >> ability >> money;
        work[i].push_back(ability);
        work[i].push_back(money);
        }
    for(int i = 0; i < M ; ++i){//保存m个小伙伴能力
        cin >> level;
        lev.push_back(level);
    } 
    int max = 0;
    for(int i = 0; i < M ; ++i){
        for(int j = 0; j < N ; ++j){
            if(lev[i] >= work[i][0] && max <= work[j][1])
                max = work[j][1];
        }
        cout << max<<endl;
    }
    return 0;
}

第二次代码:

改进:

1.需要初始化:vector<vector<int>> work(N);//N为行数

2.第一次判断条件里的下标work[i][0]写错了  改为 work[j][0]

3.增加了两次排序

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
int main()
{
    int N,M; 
    int ability,money;
    int level; 
    cin >> N >> M;
    vector<vector<int>> work(N);
    vector<int> lev;
    for(int i = 0; i < N; ++i){
        cin >> ability >> money;
        work[i].push_back(ability);
        work[i].push_back(money);
        }
	//vector<vector<int>>::iterator iter = work.begin();
	sort(work.begin(),work.end());
    for(int i = 0; i < M ; ++i){
        cin >> level;
        lev.push_back(level);
    } 
	sort(lev.begin(),lev.end());
    int max = 0;
    for(int i = 0; i < M ; ++i){
        for(int j = 0; j < N ; ++j){
			if(lev[i] >= work[j][0] && max <= work[j][1]){
                max = work[j][1];
			}
        }
        cout << max<<endl;
    }
    return 0;
}

case通过率为10.00%,继续改进!

 

 思路2:

参考了小伙伴的思路以及代码,利用map映射实现  //map会对插入数据进行排序

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
 
int main()
{
    int N,M; //工作数量 //小伙伴数量
    int Di,Pi; //工作难度 //报酬
    int Ai; //小伙伴能力值
    map<int,int> m;
    cin >> N >> M;
    //将key--value放入map中  //自动排序
    for(int i = 0;i < N;++i)
    {
        cin >> Di >> Pi;
        m.insert({Di,Pi});
    }
    //工作能力强,报酬高 //当工作强度大时,报酬一定高 //小的时候进行值覆盖
    int pay = 0;
    
    for(map<int,int>::iterator p = m.begin();p != m.end();++p)
    {
        //采取值覆盖步骤
        pay = max(pay,p->second);
        p->second = pay;
    }
    //输出对应报酬
    map<int,int>::iterator p;
    for(int i = 0;i < M;++i)
    {
        cin >> Ai;
        p = m.upper_bound(Ai);
        p--;
        cout << p->second << endl;
    }
    
    return 0;
}

成功!详情(https://blog.csdn.net/weixin_40740059/article/details/94601687

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值