8,8. 字符串转换整数 (atoi) - 力扣(LeetCode)
开始使用内置函数std::stoll但是函数转为long long 时有可能会超出long long 的大小,所以需要进行异常抛出。
class Solution {
public:
int myAtoi(string s) {
int i=0;
int n=s.size();
string tmp;
while(i<n && s[i]==' '){
i++;
}
if(i<n && (s[i]=='-' ||s[i] == '+')){
tmp +=s[i];
i++;
}
while(i<n && isdigit(s[i]) ){
tmp+=s[i];
i++;
}
if(tmp.empty() || (tmp.size()==1 &&(tmp[0]=='+' ||tmp[0]=='-'))){
return 0;
}
// long long re=std::stoll(tmp);
long long re;
try {
re = std::stoll(tmp);
} catch (const std::out_of_range& e) {
// 处理溢出
if (tmp[0] == '-') {
return INT_MIN;
} else {
return INT_MAX;
}
} catch (const std::invalid_argument& e) {
// 处理无效参数
return 0;
}
if(re<-2147483648){
return -2147483648;
}else if (re > 2147483647)
{
return 2147483647;
}else{
return (int)re;
}
}
};
11、11. 盛最多水的容器 - 力扣(LeetCode)
其实是对两个for循环进行优化,使用两个指针,一个左边开始一个右边开始,直到两个指针遇到一起结束。其中左边和右边对比谁小就移动谁。
int maxArea(vector<int>& height) {
int n=height.size();
int left=0;
int right=n-1;
int res=0;
while(left!=right){
int v=min(height[left],height[right])*(right-left);
res=max(res,v);
if(height[left]<height[right]){
left++;
}else{
right--;
}
}
return res;
}
12、12. 整数转罗马数字 - 力扣(LeetCode)
const pair<int,string> value[]{
{1000, "M"},
{900, "CM"},
{500, "D"},
{400, "CD"},
{100, "C"},
{90, "XC"},
{50, "L"},
{40, "XL"},
{10, "X"},
{9, "IX"},
{5, "V"},
{4, "IV"},
{1, "I"}
};
class Solution {
public:
string intToRoman(int num) {
string re;
for(const auto &entry:value){
int val=entry.first;
string symbol=entry.second;
while(num >= val){
num-=val;
re+=symbol;
}
if(num == 0){
break;
}
}
return re;
}
};
13、 13. 罗马数字转整数 - 力扣(LeetCode)
两种方法(一种将对比过的字符删除;一种使用标志,记录位置)
第一种:删除
const pair<string,int> value[]{
{"M", 1000},
{"CM", 900},
{"D", 500},
{"CD", 400},
{"C", 100},
{"XC", 90},
{"L", 50},
{"XL", 40},
{"X", 10},
{"IX", 9},
{"V", 5},
{"IV", 4},
{"I", 1},
};
class Solution {
public:
int romanToInt(string s) {
int re=0;
while (!s.empty()) {
bool found = false;
for (const auto &entry : value) {
string symbol = entry.first;
int val = entry.second;
if (s.substr(0, symbol.length()) == symbol) {
re += val;
s.erase(0, symbol.length());
found = true;
break;
}
}
if (!found) {
return -1;
}
}
return re;
}
};
第二种:标记
const pair<string,int> value[]{
{"M", 1000},
{"CM", 900},
{"D", 500},
{"CD", 400},
{"C", 100},
{"XC", 90},
{"L", 50},
{"XL", 40},
{"X", 10},
{"IX", 9},
{"V", 5},
{"IV", 4},
{"I", 1},
};
class Solution {
public:
int romanToInt(string s) {
int re=0;
int pos=0;
while (pos < s.size()) {
bool found = false;
for (const auto &entry : value) {
string symbol = entry.first;
int val = entry.second;
if (s.substr(pos, symbol.length()) == symbol) {
re += val;
pos += symbol.length();
found = true;
break;
}
}
if (!found) {
return -1;
}
}
return re;
}
};
14、14. 最长公共前缀 - 力扣(LeetCode)
使用键值对数组,将按照字符串大小排序,然后将最小的字符串和第二小的比较,看是否存在最长公共前缀,如果存在再比较。如果不存在就结束。
其中注意:
sort(mi.begin(), mi.end(), [](const pair<int, string>& a, const pair<int, string>& b) {
return a.first < b.first; // 升序排序
});
[](const pair<int, string>& a, const pair<int, string>& b
是Lambda 表达式:
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
int n=strs.size();
if (n == 0) return "";
vector<pair<int,string> > mi(n);
for(int i=0;i<n;i++){
mi[i].first=strs[i].size();
mi[i].second=strs[i];
}
sort(mi.begin(), mi.end(), [](const pair<int, string>& a, const pair<int, string>& b) {
return a.first < b.first; // 升序排序
});
string shortest = mi[0].second;
// 与第二短的字符串比较,找到公共前缀
string commonPrefix = shortest;
for (int i = 1; i < n; i++) {
string current = mi[i].second;
string newCommonPrefix = "";
for (int j = 0; j < commonPrefix.size() && j < current.size(); j++) {
if (commonPrefix[j] == current[j]) {
newCommonPrefix += commonPrefix[j];
} else {
break;
}
}
commonPrefix = newCommonPrefix;
if (commonPrefix.empty()) {
return ""; // 如果没有公共前缀,直接返回空字符串
}
}
return commonPrefix;
}
};
15、15. 三数之和 - 力扣(LeetCode)
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int n = nums.size();
vector<vector<int>> re;
if (n < 3) return re; // 如果数组长度小于3,直接返回空结果
sort(nums.begin(), nums.end()); // 对数组排序
for (int i = 0; i < n - 2; ++i) {
if (i > 0 && nums[i] == nums[i - 1]) continue; // 跳过重复的数字
int left = i + 1, right = n - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum == 0) {
re.push_back({nums[i], nums[left], nums[right]});
while (left < right && nums[left] == nums[left + 1]) ++left; // 跳过重复的数字
while (left < right && nums[right] == nums[right - 1]) --right; // 跳过重复的数字
++left;
--right;
} else if (sum < 0) {
++left;
} else {
--right;
}
}
}
return re;
}
};
16、16. 最接近的三数之和 - 力扣(LeetCode)
class Solution{
public:
int threeSumClosest(vector<int>& nums, int target) {
int n=nums.size();
int mi=INT_MAX;
int res=INT_MAX;
sort(nums.begin(),nums.end());
for(int i=0;i<n-2;i++){
int left=i+1;
int right=n-1;
while(left<right){
int sum=nums[i]+nums[left]+nums[right];
int cha=abs(target-sum);
if(cha<mi){
mi=cha;
res=sum;
}
if(sum>target){
right--;
}else if (sum<target)
{
/* code */
left++;
}else{
return res;
}
}
}
return res;
}
};
17、17. 电话号码的字母组合 - 力扣(LeetCode)
第一种方法就是先将可能的字符串保存起来,然后再组合
const pair<string, string> value[]{
{"2", "abc"},
{"3", "def"},
{"4", "ghi"},
{"5", "jkl"},
{"6", "mno"},
{"7", "pqrs"},
{"8", "tuv"},
{"9", "wxyz"}
};
class Solution {
public:
vector<string> letterCombinations(string digits) {
vector<string> res;
int n = digits.size();
if (n == 0) {
return res;
}
// 用于存储每个数字对应的字母字符串
vector<string> lettersList;
for (char digit : digits) {
for (const auto& entry : value) {
if (entry.first == string(1, digit)) {
lettersList.push_back(entry.second);
break;
}
}
}
// 生成所有可能的组合
return com(lettersList);
}
private:
vector<string> com(const vector<string>& lettersList) {
vector<string> result;
if (lettersList.empty()) {
return result;
}
// 递归组合函数
function<void(int, string)> backtrack = [&](int index, string current) {
if (index == lettersList.size()) {
result.push_back(current); // 如果到达字母列表的末尾,添加当前组合到结果中
return;
}
for (char c : lettersList[index]) {
backtrack(index + 1, current + c); // 递归生成下一个位置的组合
}
};
// 从第一个字母开始递归生成组合
backtrack(0, "");
return result;
}
};
303

被折叠的 条评论
为什么被折叠?



