1.反转字符串
class Solution {
public:
void reverseString(vector<char>& s) {
int i =0;
int j= s.size()-1;
while(i<j){
char tmpc = s[i];
s[i]=s[j];
s[j]=tmpc;
i++;
j--;
}
}
};
2.反转字符串II
方法一:双指针法 每次都遍历j 每次遍历的时候 j++,j如果是k的倍数 在看m m是决定是否反转
方法一:双指针法 每次都遍历j=j+2k,每次操作(j,j+k-1)进行翻转 当然如果超过数据长度 剩余的进行翻转即可
方法一:
class Solution {
void reverseStr(string &s,int i,int j){
while(i<j){
char temp = s[i];
s[i]=s[j];
s[j]=temp;
i++;
j--;
}
}
public:
string reverseStr(string s, int k) {
int i=0;
int m =0;
for(int j=0;j<s.size();j++){
if((j+1)%k==0){
if(m%2==0){
// 需要将前k个进行交换
reverseStr(s,i,j);
cout<<" i"<<i<<" j"<<j<<endl;
}else{
// 不需要交换前k个
}
m++;
i=j+1;
}else if(j==s.size()-1&&m%2==0){
// 发现不足k个 并且需要反转
reverseStr(s,i,j);
}
}
return s;
}
};
方法二:
class Solution {
void reverseStr(string &s,int i,int j){
while(i<j){
char temp = s[i];
s[i]=s[j];
s[j]=temp;
i++;
j--;
}
}
public:
string reverseStr(string s, int k) {
int i=0;
int m =0;
for(int j=0;j<s.size();j=j+2*k){
if(j+k-1>=s.size()){
reverseStr(s,j,s.size()-1);
}else{
reverseStr(s,j,j+k-1);
}
}
return s;
}
};
移除元素(为下面的翻转字符串里的单词做铺垫 双指针移除多余空格)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int left =0;
for(int right =0;right<nums.size();right++){
if(nums[right]!=val){
nums[left]=nums[right];
left++;
}
}
return left;
}
};
3.翻转字符串里的单词
主要思路 :
1.先去除所有多余空格(先去首空格 然后 中间空格以及尾部保留一个即可,尾空格再次判断一下即可 最后通用resize从新改变字符串的长度)
2.遍历翻转 遇见空格就翻转 但是最后单词是没有翻转的机会的 直接判断一下即可
完整代码如下:
class Solution {
public:
void removeExtraSpaces(string& s) {
int slow =0;
bool needspace =false;
for(int fast =0;fast<s.size();fast++){
if(s[fast]!=' '){
s[slow++]=s[fast];
needspace = true;
}else if(s[fast]==' '&&needspace==true){
s[slow++]=' ';
needspace = false;
}
}
// 最后一个位置 可能是空的
if(s[slow-1]==' '){
s.resize(slow-1);
}else{
s.resize(slow);
}
}
string reverseWords(string s) {
removeExtraSpaces(s); //去除多余空格,保证单词之间之只有一个空格,且字符串首尾没空格。
reverse(s.begin(),s.end());
int slow = 0;
for(int fast =0;fast<s.size();fast++){
if(s[fast]==' '){
reverse(s.begin()+slow,s.begin()+fast);
slow=fast+1;
}
// 明显还剩最后一个单词
if(fast==s.size()-1){
reverse(s.begin()+slow,s.end());
}
}
return s;
}
};
4.实现strStr()
见kmp算法章节
5.重复的子字符串
见kmp算法章节
补充字符串题目:
两个大数相加
class Solution {
public:
string addStrings(string num1, string num2) {
int len1 = num1.size();
int len2 = num2.size();
if(len1>len2){
int gab = len1-len2;
while(gab--){
num2="0"+num2;
}
}else if(len1<len2){
int gab = len2-len1;
while(gab--){
num1="0"+num1;
}
}
cout<<num1<<" "<<num2<<endl;
string ret="";
int ok=0;
for(int i=num1.size()-1;i>=0;i--){
int temp= num1[i]-'0'+num2[i]-'0'+ok;
if(temp>9){
temp=temp%10;
ret=to_string(temp)+ret;
ok=1;
}else{
ok=0;
ret=to_string(temp)+ret;
}
}
if(ok==1){
ret="1"+ret;
}
return ret;
}
};
两个字符串的16进制加法
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
#include<string>
#include <cassert>
using namespace std;
class Solution {
int getIntFomChar(char c) {
if (c>='0'&& c <= '9') {
return c - '0';
}
else if (c >= 'a' && c <= 'z') {
return c - 'a' + 10;
}
cout << "异常数据" << endl;
return -1;
}
public:
string addStrings(string num1, string num2) {
string symbol = "0123456789abcdefghijklmnopqrstuvwxyz";
cout << symbol.size() << endl;
int len1 = num1.size();
int len2 = num2.size();
if (len1 > len2) {
int gab = len1 - len2;
while (gab--) {
num2 = "0" + num2;
}
}
else if (len1 < len2) {
int gab = len2 - len1;
while (gab--) {
num1 = "0" + num1;
}
}
cout << num1 << " " << num2 << endl;
string ret = "";
int ok = 0;
for (int i = num1.size() - 1; i >= 0; i--) {
int temp = getIntFomChar(num1[i]) + getIntFomChar(num2[i]) + ok;
if (temp > 35) {
temp = temp % 36;
ret = symbol[temp] + ret;
ok = 1;
}
else {
ok = 0;
ret = symbol[temp] + ret;
}
}
if (ok == 1) {
ret = "1" + ret;
}
return ret;
}
};
int main() {
string num1 = "109z";
string num2 = "11";
Solution s;
auto ret = s.addStrings(num1, num2);
cout << ret << endl;
}