DAY 12
1.AcWing 872. 最大公约数
考察点:最大公约数 欧几里得算法(辗转相除法)
欧几里德算法
结论: gcd(a,b)=gcd(b,a mod b)
具体代码及模板如下:
#include<iostream>
using namespace std;
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;//核心模板 需要重点记忆
}
int main()
{
int n;
cin>>n;
while(n--)
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",gcd(a,b));
}
return 0;
}
2.LeetCode:151.翻转字符串里的单词
考察点:使用双指针删除单词中的空格 翻转字符串
整体反转+局部反转
所以解题思路如下:
- 移除多余空格
- 将整个字符串反转
- 将每个单词反转
具体实现代码如下:
方法一是先删除队头的空格再删去队内的重复空格最后再删去结尾的空格。
方法二是先删除所有的空格,之后根据单词来进行补空格
方法二相较于方法一更加简洁
class Solution {
public:
// 反转字符串s中左闭又闭的区间[start, end]
void reverse(string &s,int start,int end)
{
for(int i = start,j = end;i<j;i++,j--)
{
swap(s[i],s[j]);
}
}
//方法一 去除空格
void removeExtraSpaces(string &s)
{
int fastIndex = 0,slowIndex = 0;
//去掉字符串前面的空格
while(s.size()>0&&fastIndex<s.size()&&s[fastIndex] == ' ')
{
fastIndex++;
}
for(;fastIndex<s.size();fastIndex++)
{
//去掉中间重复的空格
if(fastIndex-1>0&&s[fastIndex] == s[fastIndex-1]&&s[fastIndex] == ' ')
{
continue;
}
else
{
s[slowIndex++] = s[fastIndex];
}
}
if(slowIndex-1>0&&s[slowIndex-1] == ' ')
{
//删去末尾的空格
s.resize(slowIndex - 1);
}
else s.resize(slowIndex);// 重新设置字符串大小
}
/*
//方法二 去除空格
void removeExtraSpaces(string& s)
{
//去除所有空格并在相邻单词之间添加空格, 快慢指针。
int slow = 0;
for (int i = 0; i < s.size(); ++i)
{ //
if (s[i] != ' ')
{
//遇到非空格就处理,即删除所有空格。
if (slow != 0) s[slow++] = ' '; //手动控制空格,给单词之间添加空格。slow != 0说明不是第一个单词,需要在单词前添加空格。
while (i < s.size() && s[i] != ' ')
{
//补上该单词,遇到空格说明单词结束。
s[slow++] = s[i++];
}
}
}
s.resize(slow); //slow的大小即为去除多余空格后的大小。
}*/
string reverseWords(string s)
{
removeExtraSpaces(s); //去除多余空格,保证单词之间之只有一个空格,且字符串首尾没空格。
reverse(s, 0, s.size() - 1);
int start = 0; //removeExtraSpaces后保证第一个单词的开始下标一定是0。
for(int i=0;i<=s.size();++i)
{
if(i == s.size()||s[i] == ' ')
{
//到达空格或者串尾,说明一个单词结束。进行翻转。
reverse(s, start, i - 1); //翻转,注意是左闭右闭 []的翻转。
start = i + 1; //更新下一个单词的开始下标start
}
}
return s;
}
};
3.剑指 Offer 05. 替换空格
考察点:双指针
具体实现代码如下:
class Solution {
public:
string replaceSpace(string s)
{
int count = 0;//统计空格的个数
int sOldsize = s.size();
for(int i = 0;i<s.size();i++)
{
if(s[i]==' ') count++;
}
// 扩充字符串s的大小,也就是每个空格替换成"%20"之后的大小
s.resize(s.size()+count*2);
int sNewsize = s.size();
// 从后先前将空格替换为"%20"
for(int j = sOldsize-1,i = sNewsize-1;j<i;i--,j--)
{
if(s[j]!=' ')
{
s[i] = s[j];
}
else
{
s[i] = '0';
s[i-1] = '2';
s[i-2] = '%';
i-=2;
}
}
return s;
}
};
4.剑指Offer58-II.左旋转字符串
考察点:整体反转+局部反转
具体实现代码如下:
class Solution {
public:
string reverseLeftWords(string s, int n)
{
reverse(s.begin(),s.begin()+n);
reverse(s.begin()+n,s.end());
reverse(s.begin(),s.end());
return s;
}
};