题号2575.找出字符串的可整除数组
完整code
class Solution {
public:
vector<int> divisibilityArray(string word, int m) {
// 遍历
long long sum = 0;
vector<int> res;
for(int i = 0; i< word.size(); i++) {
sum = (sum*10 + word[i] - '0') % m;
// 超出范围
if(sum) {
res.push_back(0);
} else {
res.push_back(1);
}
}
return res;
}
};
关键点
如果不按照上面写法, 会溢出
题号2834.找出美丽数组的最小和
特别提示: 做题一定需要事先考虑 数据类型
简单来说就是考虑溢出问题
思路
- 判断左右边的条件
- 设置 min_sun 相加
判断条件
左边
对于 target 来说
1 和 target -1 只能选一个
2 和 target -2 只能选一个
3 和 target -3 只能选一个
…
一直到 [ target/2 ]
右边
target + 1
target + 2
target + 3
…
但是需要注意个数 以及 数组长度的关系h
(因为 左边有可能直接就够 n , 就不需要右边了 )
举例
n = 5 target = 7
( 1 2 3 ) 4 5 6 [7 8]
左边用括号 右边用中括号
对于左边: 为什么不取 4 ? 因为 3 + 4 = 7 , 加上也不符合我们的判断条件 , 4 > 7/2
右边自然简单
注意
这里题目的数据取值范围是
1 <= n <= 10^9
1 <= target <= 10^9
iint 类型的范围是从 -2,147,483,648 (-2^31) 到 2,147,483,647 (2^31 - 1)。
所以 需要用 long long ,不然会溢出
code
普通循环法
class Solution {
public:
int minimumPossibleSum(int n, int target) {
const int mod = 1e9 + 7;
if(n == 1 && target == 1) {
return 1;
}
// 遍历 target-1 -2 -3 ..
long long min_sum = 0;
int k = 0; // 记录个数
for(int i= 1; i<= target/2; i++) {
min_sum+= i;
k++;
if(k >= n) {
break;
}
}
// 开始加上后面
for(int i = k; i< n; i++) {
min_sum+= target;
target++;
}
return min_sum % mod;
}
};
数学法
class Solution {
public:
int minimumPossibleSum(int n, int target) {
const int mod = 1e9 + 7;
int m = target / 2;
if (n <= m) {
return (long long) (1 + n) * n / 2 % mod;
}
return ((long long) (1 + m) * m / 2 +
((long long) target + target + (n - m) - 1) * (n - m) / 2) % mod;
}
};
废话
刚开始, 读到题目说不存在 nums[i] + nums[j] == target
我就想起之前的两数之和的题目
我刚开始想的是 以 target 作为分界
把左边符合条件 相加
然后 把右边符合条件 相加
最后返回结果
但是在这里, 我犯下致命的错误, 下面我和大家唠嗑唠嗑
举个例子
n = 16
target = 6
就是一个 数组长度为 16 , 然后里面任意两个数 不等于 6 并且数组是由不等的正整数 组成的
我刚开始的想法
6 为 分界线
左边: 1 2 3 4 5
( 我刚开始认为左边判断条件为 ( i+1 < target ))
右边:
( i > target )
算出来的结果 比 标准答案要小
但是 你只要仔细看就会发现 2 + 4 = 6
毫无疑问, 判断条件出现了问题
2129.将标题首字母大写
思路一
- 利用 istringstream 函数进行分割成 字符串输入
- 遍历并且利用 toupper、 toupper、substr 函数实现
函数istringstream
默认情况下, 对字符串以空格进行分割,并且输出子字符串
注意: 多个空格被认为是一个空格
举例说明
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string inputString = "Hello World 2022";
istringstream iss(inputString);
string word1, word2;
int year;
// 从 iss 中提取字符串和整数
iss >> word1;
iss >> word2;
iss >> year;
cout << "Word1: " << word1 << endl;
cout << "Word2: " << word2 << endl;
cout << "Year: " << year << endl;
return 0;
}
如果不喜欢库函数
char toUpper(char c) {
if (c >= 'a' && c <= 'z') {
return c - 'a' + 'A';
}
return c;
}
char toLower(char c) {
if (c >= 'A' && c <= 'Z') {
return c - 'A' + 'a';
}
return c;
}
完整code
class Solution {
public:
string capitalizeTitle(string title) {
// 字符串分割
istringstream iss(title);
string ans,s;
while(iss >> s) {
if(!ans.empty()) {
ans += ' ';
}
// 首字母大写
if(s.length() > 2) {
ans += toupper(s[0]); // 字符大写
s = s.substr(1);
}
for(int i = 0; i< s.size(); i++) {
ans += tolower(s[i]); // 字符小写
}
}
return ans;
}
};
写法二: 双指针遍历 ( 不使用分割库函数 )
关键点:
- 设置 l 以及 r
- 在遍历开始前, title 字符串后面添加空格
完整code
class Solution {
public:
string capitalizeTitle(string title) {
// 双指针遍历
int l = 0;
int r = 0;
// 字符串长度
title.push_back(' ');
int n = title.size();
while(r < n) {
if(title[r] != ' ') {
r++; // 右边移动
}
// 遇到空格 停止进行处理 并且修改一下 l 以及 r 的值
if(title[r] == ' ') {
// 判断长度
if(r-l > 2) {
title[l] = toupper(title[l]);
l++;
}
// 后面变小写
while(l < r) {
title[l] = tolower(title[l]);
l++;
}
// 重新修改 l 以及 r 的值
l++;
r++;
}
}
title.pop_back();
return title;
}
};