文章目录
剑指offer 02——替换空格
题目描述
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
解题思路
1.第一次遍历找出空格的个数
2.字符串转char*
3.定义前后指针,遍历字符转替换
代码
string replaceSpace(string s) {
// write code here
//空格个数
int num1 = 0;
for(char var : s)
if(var == ' ')
++num1;
int len_new = s.size() + 2 * num1;
//转char*操作
char* ch = (char*)s.c_str();
int i = s.size();
int j = len_new;
while(i != j){
if(ch[i] != ' ')
ch[j--] = ch[i--];
else{
ch[j--] = '0';
ch[j--] = '2';
ch[j--] = '%';
i--;
}
}
return ch;
}
剑指offer 27——字符串的排列
题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则按字典序打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
输入
“ab”
返回值
[“ab”,“ba”]
解题思路
1.递归加回溯
2.每次固定一个字符,固定完后退回到起始状态(回溯)
代码
void fun(int num, string s, set<string> &ret) {
if(num+1 == s.size())
ret.insert(s);
for(int i = num; i < s.size(); ++i) {
//固定
swap(s[i], s[num]);
//固定下一个字符
fun(num+1, s, ret);
//回溯
swap(s[i], s[num]);
}
}
vector<string> Permutation(string str) {
if(str.size() == 0) return {};
set<string> res;
fun(0, str, res);
return vector<string>{res.begin(), res.end()};;
}
剑指offer 32——把数组排成最小的数
题目描述
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
输入
[3,32,321]
返回值
“321323”
解题思路
1.利用自带的sort函数,自定义排序规则
2.将int转换为string,便于拼接和大小比较
3.如果a + b < b + a, 我们此时希望a排在b的前面,我们可以根据这个逻辑自定义排序规则
代码
string PrintMinNumber(vector<int> numbers) {
vector<string> input;
for(int k : numbers) {
input.push_back(to_string(k));
}
//使用匿名lamdba表达式定义排序规则
sort(input.begin(), input.end(), [](string a, string b){
return a + b < b + a;
});
string str = "";
for(string s : input)
str += s;
return str;
}
剑指offer 43——左旋转字符串
题目描述
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
输入
“abcXYZdef”,3
返回值
“XYZdefabc”
解题思路
1.暴力解决
2.先将n 到 size()-1位放进返回字符串
3.再将0 到 n -1位放进返回字符串
代码
string LeftRotateString(string str, int n) {
if(n >= str.size())
return str;
string res = "";
for(int i = n; i < str.size(); ++i)
res += str[i];
for(int i = 0; i < n; ++i)
res += str[i];
return res;
}
剑指offer 44——翻转单词序列
题目描述
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
输入描述:
输入
“nowcoder. a am I”
返回值
“I am a nowcoder.”
解题思路
- 从右向左遍历
- 根据空格划分单词
- 定义一个bool标记,用于记录是否已经包含一个单词
代码
string ReverseSentence(string str) {
int i = 0, sz = str.size();
for(char c : str)
if(c == ' ')
++i;
//当前是否全为空格
if(i == sz) return str;
bool hasstr = false;
string res = "";
string tmpstr = "";
for(i = sz - 1; i >= 0; --i) {
if(str[i] == ' ' && hasstr) {
res += tmpstr + ' ';
tmpstr = "";
hasstr = false;
}
else if(str[i] != ' ') {
tmpstr = str[i] + tmpstr;
hasstr = true;
}
}
if(hasstr)
res += tmpstr;
return res;
}
剑指offer 49——把字符串转换成整数
题目描述
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0
输入描述:
输入
“+2147483647”
返回值
2147483647
解题思路
- 排除队首的空格
- 确定数字开头是否存在正负号
- 遍历时如果出现非法字符,退出循环
- 根据 i 是否等于size()判断是否返回数字
代码
int StrToInt(string str) {
int len = str.size();
if(len == 0) return 0;
int i = 0;
while(i < len && str[i] == ' ') ++i;
if(i == len) return 0;//全为空格
//非法字符
if(!isdigit(str[i]) && str[i] != '+' && str[i] != '-')
return 0;
bool neg = (str[i] == '-');
i = isdigit(str[i]) ? i : i+1;
long long ret = 0L;
while(i < len && isdigit(str[i])) {
ret = ret*10 + str[i++] - '0';
//超出边界判断
if(!neg && ret > INT_MAX) {
ret = INT_MAX;
break;
}
//超出边界判断
if(neg && ret > 1L + INT_MAX){
ret = 1L + INT_MAX;
break;
}
}
if(i != len) return 0;
return neg ? static_cast<int>(-ret) : static_cast<int>(ret);
}
剑指offer 54——字符流中第一个不重复的字符
题目描述
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
返回值描述:
如果当前字符流没有存在出现一次的字符,返回#字符。
解题思路
- 排除队首的空格
- 确定数字开头是否存在正负号
- 遍历时如果出现非法字符,退出循环
- 根据 i 是否等于size()判断是否返回数字
代码
//当前字符队列(无重复)
queue<char> q;
//用来记录当前字符出现的次数
map<char, int> mp;
void Insert(char ch) {
if(mp.find(ch) == mp.end())
q.push(ch);
++mp[ch];
}
//return the first appearence once char in current stringstream
char FirstAppearingOnce() {
while(!q.empty()) {
char ch = q.front();
if(mp[ch] == 1) {
return ch;
}
else {
q.pop();
}
}
return '#';
}