开始刷题:
一、替换空格
题目描述:请实现一个函数,将一个字符串中的每个空格替换成“%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)
语法:
|
append() 函数可以完成以下工作:
查找(find)
- 在字符串的末尾添加str,
- 在字符串的末尾添加str的子串,子串以index索引开始,长度为len
- 在字符串的末尾添加str中的num个字符,
- 在字符串的末尾添加num个字符ch,
- 在字符串的末尾添加以迭代器start和end表示的字符序列.
语法:
|
find()函数:
- 返回str在字符串中第一次出现的位置(从index开始查找)。如果没找到则返回string::npos,
- 返回str在字符串中第一次出现的位置(从index开始查找,长度为length)。如果没找到就返回string::npos,
- 返回字符ch在字符串中第一次出现的位置(从index开始查找)。如果没找到就返回string::npos
删除(erase)
语法:
|
erase()函数可以:
- 删除pos指向的字符, 返回指向下一个字符的迭代器,
- 删除从start到end的所有字符, 返回一个迭代器,指向被删除的最后一个字符的下一个位置
- 删除从index索引开始的num个字符, 返回*this.
c_str语法:
-
const char *c_str();
c_str()函数返回一个指向正规C字符串的指针, 内容与本字符串相同.
插入(insert)
语法:
|
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)