344. 文字列を反転する
提案: この質問は、文字列に関する基本的な質問であり、逆関数の実現を調査するものですが、同時に、ライブラリ関数をいつ使用するか、いつ使用しないのかも明確です。ライブラリ関数は、次のことしかできません。問題解決の一部である場合に使用されます
トピックリンク: Lituo
アイデア: この質問ではスワップ関数を使用します。
class Solution {
public:
void reverseString(vector<char>& s) {
for(int i=0,j=s.size()-1;i<s.size()/2;i++,j--)
{
swap(s[i],s[j]);
}
}
};
541. 文字列を反転する II
提案: この質問は再び高度なものです。最初に独立して問題を解いてから、解決策を読むと、コーディング スキルを深く理解できるようになります。
トピックリンク: Lituo
考え方:各処理は2kずつ処理し、その都度kを反転し、2kで足りない場合は全部反転する。ループでは 2k が走査されます。ここで使用する関数はリバース関数です。reverse(i, i+k) 関数を逆にすると、左が閉じられ、右が開かれることに注意してください。
次のコードで注意が必要な箇所が 1 か所あります。それは、変換プロセス中に s.begin() + 特定の数値があることです。コードを書いているときに、s.begin() とコードを忘れてしまいました。常にコンパイルできません。
class Solution {
public:
string reverseStr(string s, int k) {
//首先是以2k为循环,依次进行下去
for(int i = 0;i<s.size();i+=(2*k))
{
if(i+k<=s.size())
{
reverse(s.begin()+i,s.begin()+i+k);
continue;//跳出循环
}
//最后剩下的那一点
reverse(s.begin()+i,s.begin()+s.size());
}
return s;
}
};
Sword Pointer Offer 05. スペースを置き換える
提案: 線形データ構造の場合、入力または削除、注文後の処理がはるかに効率的になります。良い経験をしてください。
トピックリンク: Lituo
class Solution {
public:
string replaceSpace(string s) {
//首先记录空格的数量
int count_space = 0;
for(int i = 0;i < s.size();i++)
{
if(s[i]==' ')
{
count_space++;
}
}
int oldsize = s.size();
s.resize(s.size()+count_space*2);
int newsize = s.size();
//开始从后往前进行遍历
for(int i = newsize-1,j=oldsize-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;
}
};
151. 文字列内の単語を反転する
提案: この質問は基本的に、実行されたすべての文字列操作をカバーしていますが、問題を解決するアイデアを知っていても、この質問のコードを書くのは簡単ではないため、さらに練習する必要があります。
アイデア: __wo_he__ -> wo_he -> ow_eh -> wo_he
消去の時間計算量は O(n) であり、時間計算量が増加しているため、消去は使用しないでください。例: if () {1 回消去} したがって、ここではダブルポインタメソッドを使用して解決します。
高速ポインタを定義し、低速ポインタを定義します。
class Solution {
public:
void reverse(string &s,int begin,int end)
{
for(int i = begin,j = end;i<j;i++,j--)
{
swap(s[i],s[j]);
}
}
//这道题比较难,看视频没有看明白,按照自己的思路来
//首先是移除空格,所有的字母之间只是存在一个空格并且首尾字母之间不存在空格
void removeBlank(string &s)
{
int slow = 0;//慢指针
for(int i = 0;i<s.size();i++)
{
if(s[i]!=' ')//判断不为空的情况
{
if(slow!=0) s[slow++]=' ';//判断是否是第一个字母
while(i<s.size()&&s[i]!=' ')
{
s[slow++]=s[i++];
}
}
}
//删除空格
s.resize(slow);
}
string reverseWords(string s) {
removeBlank(s);//去除空格
reverse(s,0,s.size()-1);//翻转一下
int start = 0;
for(int i = 0;i<s.size();i++)
{
if((i != (s.size()-1)) && (s[i]==' '))//注意条件,到达尾端
{
reverse(s,start,i-1);
start = i+1;//这句代码写错了,导致我浪费了很多时间
}
else if(i == (s.size()-1))
{
reverse(s,start,i);
}
}
return s;
}
};
Offer58-II を指す剣。文字列を左に回転
1 つ目は、最初の n 個の文字列を反転し、次に最後の n 個の文字列を反転して、全体の反転を実行することです。
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;
}
};