万人千题计划
推荐博主
1.英雄哥每天给我们筛选题目,真的非常辛苦,很感谢他,大家可以看看他的专栏,对新手很有帮助,对一些有基础的人更是能温故知新
2.秋名山码民我的小师弟,是个卷王,他的文章也很有趣
3.执久呀我们群里的拼命三郎,老能卷了
千位分隔数
思路:新开一个字符串,遍历字符串,每三位插入一个分隔符
class Solution {
public:
string thousandSeparator(int n) {
if(n == 0) return "0";
string res = to_string(n);
int size = res.size();
while(size) {
size -= 3;
if(size<=0) break;
res.insert(size, ".");
}
return res;
}
};
字符串转化后的各位数字之和
思路:字符转成数字,循环求各位数字之和,在循环未结束之前,用把res字符串化后赋给str1
class Solution {
public:
int getLucky(string s, int k) {
int res;
string str1;
for(auto &c: s) {
str1 += to_string(c - 'a' + 1);
}
for(int i=0; i<k; i++) {
res = 0;
for(auto &c1 : str1) {
res += c1 - '0';//字符串减0后成为整数
}
str1 = to_string(res);
}
return res;
}
};
字符串中第二大的数字
思路:用双指针来写,字符串挨个比较,替换就好,
需要注意的是:一开始赋值给max1和max2只能赋-1,我试了INT_MIN,出来时时错的
class Solution {
public:
int secondHighest(string s) {
int max1 = -1, max2 = -1;
for(char &c : s) {
if(c >='0' && c <= '9') {
int temp = c - '0';
if(temp > max1) {
max2 = max1;
max1 = temp;
}else if(temp < max1 && temp > max2) {
max2 = temp;
}
}
}
return max2;
}
};
最小时间差
思路:把字符串转换成数组,进行排序后在比较。同时,进行特殊情况的处理,(23:59, 00:00)
stoi函数:把string类型转化成int类型
s.substr(a,b):返回一个string,包含s中从a开始的b个字符的拷贝
class Solution {
public:
int findMinDifference(vector<string>& timePoints) {
int n = timePoints.size();
int times[n];
for (int i = 0; i < n; ++i) {
times[i] = stoi(timePoints[i].substr(0,2))*60 + stoi(timePoints[i].substr(3,2));
}
sort(times, times+n);
int res = INT_MAX;
for (int i = 0; i < n-1; ++i) {
res = min(res, times[i+1]-times[i]);
}
// 最后一个还要和第一个比较
res = min(res, 24*60+times[0] - times[n-1]);
return res;
}
};
罗马数字转整数
思路:首先建立一个HashMap来映射符号和值,然后对字符串从左到右来,如果当前字符代表的值不小于其右边,就加上该值;否则就减去该值。以此类推到最左边的数,最终得到的结果即是答案
class Solution {
public:
int romanToInt(string s) {
unordered_map<char, int> map = {{'I',1}, {'V',5}, {'X',10}, {'L',50}, {'C',100}, {'D',500}, {'M',1000}};
int sum = map[s.back()];//返回的的是最后一个元素的引用。
for(int i=s.size()-2; i>=0; i--) {
sum += (map[s[i]] < map[s[i+1]] ? -map[s[i]] : map[s[i]]);
}
return sum;
}
};
整数转罗马数字
思路:两个字符串数组的值和下标对应,然后用贪心算法
class Solution {
public:
string intToRoman(int num) {
int values[]={1000,900,500,400,100,90,50,40,10,9,5,4,1};
string roman[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
string res;
for(int i=0; i<13; i++){//数组values的大小
while(num>=values[i]){
num -= values[i];
res += roman[i];
}
}
return res;
}
};
字符串压缩
思路:遍历字符串,将首次遇到的字符加入到res字符串中,
然后跳过重复字符并计数,直到遇到新的字符,
然后把其个数加到res后面,最后进入下一次循环前,将计数重新置1
不过我看他的题目标签说是有双指针,把其他题目搞完之后,看能不能给大家整个双指针的思路出来
class Solution {
public:
string compressString(string S) {
string res = "";
int cnt = 1;
for(int i=0; i<S.size(); i++) {
res += S[i];
while(S[i] == S[i+1]) {
i++;
cnt++;
}
res += to_string(cnt);
cnt = 1;
}
if(res.size() >= S.size()) return S;
return res;
}
};
字符串相加
思路:
class Solution {
public:
string addStrings(string num1, string num2) {
int i = num1.length() - 1, j = num2.length() - 1, add = 0;
string res = "";
while (i >= 0 || j >= 0 || add != 0) {
int x = i >= 0 ? num1[i] - '0' : 0;
int y = j >= 0 ? num2[j] - '0' : 0;
int result = x + y + add;
res.push_back('0' + result % 10);
add = result / 10;
--i;
--j;
}
// 计算完以后的答案需要翻转过来
reverse(res.begin(), res.end());
return res;
}
};
二进制求和
思路:
1、首先让两个字符串等长,若不等长,在短的字符串前补零,否则之后的操作会超出索引。
2、然后从后到前遍历所有的位数,同位相加,用的是字符相加,利用 ASCII 码,字符在内部都用数字表示,我们不需要知道具体数值,但可知 ‘0’-‘0’ = 0, ‘0’+1=‘1’,以此类推 。(字符的加减,大小比较,实际上都是内部数字的加减,大小比较)
class Solution {
public:
string addBinary(string a, string b)
{
int asize = a.size(), bsize = b.size();
while (asize > bsize) {//补齐
b = '0' + b;
bsize++;
}
while (asize < bsize) {
a = '0' + a;
asize++;
}
int carry = 0; //进位
for (int i = asize - 1; i >= 0; i--) {
int sum = a[i] - '0' + b[i] - '0' + carry;
a[i] = (sum) % 2+'0';//本位数值
carry = sum / 2;//进位更新
}
//有溢出
if (carry > 0) a = '1' + a;
return a;
}
};
检查某单词是否等于两单词之和
思路:获取字符串 firstWord、secondWord 和 targetWord 对应的整数的值,然后把前两个相加,判断其和是否等于后者
class Solution {
public:
bool isSumEqual(string firstWord, string secondWord, string targetWord) {
int first = 0, second = 0, target = 0;
for(auto &c : firstWord) first = c - 'a' + first*10;
for(auto &c : secondWord) second = c - 'a' + second*10;
for(auto &c : targetWord) target = c - 'a' + target*10;
return (first + second) == target;
}
};
字符串相乘
思路:都在代码里了
class Solution {
public:
string multiply(string num1, string num2) {
//特殊情况的处理
if(num1=="0" || num2=="0") return "0";
if(num1=="1") return num2;
if(num2=="1") return num1;
if(num1.size() < num2.size()) //大数×小数,效率高一些
swap(num1,num2);
int m = num1.size(), n = num2.size();
//提前开一个足够大的string,m位数和n位数的乘法结果不会超过m+n位数
string res(m+n,'0');
for(int i = n-1; i>=0; --i){
if(num2[i]=='0') continue;
int carry = 0; //进位
for(int j = m-1; j>=0; --j){
//先乘后加再进位
int new_num = (num1[j]-'0')*(num2[i]-'0') + (res[i+j+1]-'0') + carry;
carry = new_num / 10;
new_num = new_num % 10;
res[i+j+1] = char(new_num + '0');
}
if(carry > 0) res[i] = char(carry + '0');
}
int i = 0;
while(res[i] == '0') i++;
return res.substr(i,m+n-i); //去掉前面多余的0
}
};
整数转换成英文表示
思路:放弃抵抗,力扣官方的题解(递归)
真有点搞人心态的一道题目,建议大家用有道英语查一下单词
class Solution {
public:
vector<string> singles = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"};
vector<string> teens = {"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
vector<string> tens = {"", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
vector<string> thousands = {"", "Thousand", "Million", "Billion"};
string numberToWords(int num) {
if (num == 0) {
return "Zero";
}
string sb;
for (int i = 3, unit = 1000000000; i >= 0; i--, unit /= 1000) {
int curNum = num / unit;
if (curNum != 0) {
num -= curNum * unit;
string curr;
recursion(curr, curNum);
curr = curr + thousands[i] + " ";
sb = sb + curr;
}
}
while (sb.back() == ' ') {
sb.pop_back();
}
return sb;
}
void recursion(string & curr, int num) {
if (num == 0) {
return;
} else if (num < 10) {
curr = curr + singles[num] + " ";
} else if (num < 20) {
curr = curr + teens[num - 10] + " ";
} else if (num < 100) {
curr = curr + tens[num / 10] + " ";
recursion(curr, num % 10);
} else {
curr = curr + singles[num / 100] + " Hundred ";
recursion(curr, num % 100);
}
}
};
从早上八点到下午一点,五个小时,不敢懈怠。
这最后一题,我完成不了,希望大家能够理解,
大致思路的话,就是动态数组配递归
今天的任务就暂且告一段落,准备上课了,大家明天见