if(nums[fastIndex] != val) {
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
}
return slowIndex;
}
};
class Solution {
public:
void reverseString(vector& s) {
for(int i = 0,j = s.size()-1; i < s.size()/2; i++,j–) {
swap(s[i],s[j]);
}
}
};
class Solution {
public:
string replaceSpace(string s) {
/**
思路:
1.双指针(一个指针指向旧的字符串末尾ptr1,一个指针指向扩容后的字符串末尾ptr2)
2.对原字符串的扩容,因为%20是占3个空格的,所以要在原来一个空格基础上进行扩容
3.当遇到不是空格的时候,两个指针指向的字符就正常赋值,如果当ptr1指向空格的时候
ptr2就前面的3个空格 填上%20
*/
int count = 0;//记录空格数
int oldSize = s.size();
for(int i = 0; i < s.size(); i++) {
if(s[i] == ’ '){
count++;
}
}
s.resize(oldSize+2*count);
int newSize = s.size();
//i和j模拟指针
for(int i = oldSize-1,j = newSize-1; i>=0; i–,j–) {
if(s[i] == ’ '){
s[j] = ‘0’;
s[j-1] = ‘2’;
s[j-2] = ‘%’;
j = j-2;
}else{
s[j] = s[i];
}
}
return s;
}
};
class Solution {
public:
/**
思路:
1.去除空格(字符串前面的空格 字符串中间冗余的空格 字符串后面的空格)
2.反转字符串
3.将每个单词进行反转
**/
void removespacing(string &s) {
int slowIndex = 0,fastIndex = 0;//定义快慢指针(最终慢指针为去完冗余空格的字符串)
//去除字符串前面的空格
while(s[fastIndex] == ’ '){
fastIndex++;
}
for( ; fastIndex < s.size(); fastIndex++) {
//去除冗余的空格
if(fastIndex-1 > 0 &&
s[fastIndex-1] == s[fastIndex]
&& s[fastIndex] == ’ '){
continue;
}else {
s[slowIndex] = s[fastIndex];
slowIndex++;
}
}
//去除末尾的空格(如果字符串的末尾有多个空格的话 上方只能处理到末尾只有一个空格)
if(slowIndex-1 > 0 && s[slowIndex - 1] == ’ '){
s.resize(slowIndex-1);
}else{
s.resize(slowIndex);
}
}
void reverseStr(string &s,int start,int end){
for(int i = start,j = end; i < j; i++,j–) {
swap(s[i],s[j]);
}
}
string reverseWords(string s) {
removespacing(s);
reverseStr(s,0,s.size() - 1);
for(int i = 0; i < s.size(); i++) {
int j = i;
//找到空格
while(j < s.size() && s[j] != ’ ') {
j++;
}
reverseStr(s,i,j-1);//这里j-1是因为s[j]已经表示的是空格了
i = j;
}
return s;
}
};
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* temp;//存放临时结点
ListNode* cur = head;
ListNode* pre = NULL;
while(cur) {
temp = cur->next;
cur->next = pre;//调转指针
pre = cur;//往后移动一个结点
cur = temp;
}
return pre;//当cur指向5的时候 下一个就指向空 那么pre = cur 则就表示前指针表示指向的是5
}
};
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
/**
思路:
1.双指针(慢指针p1,快指针p2)
2.要删除倒数第n个结点,也就是要正向删除 第(总的节点数 - n)个结点
3.为了处理倒数问题,先让p2往后移动n个结点,(这时候p2还剩下(总的节点数-n = sum)),那么此时
p1和p2一块移动,等到p2指向末尾的时候,p1也就指向要删除的结点
*/
ListNode* fakeNode = new ListNode(0);
fakeNode->next = head;
ListNode* slowNode = fakeNode;//慢指针
ListNode* fastNode = fakeNode;//快指针
while(n-- && fastNode != NULL) {
fastNode = fastNode->next;
}
fastNode = fastNode->next;//让其再快一格是为了当快指针到末尾的时候,慢指针指向要删除结点的
//的前一个结点
while(fastNode != NULL){
fastNode = fastNode->next;
slowNode = slowNode->next;
}
slowNode->next = slowNode->next->next;
return fakeNode->next;
}
};
class Solution {
public:
vector<vector> fourSum(vector& nums, int target) {
vector<vector >ans;
vector v;
sort(nums.begin(),nums.end());
for(int i = 0; i < nums.size(); i++) {
if(i > 0 && nums[i-1] == nums[i]) {
continue;
}
for(int j = i+1; j < nums.size(); j++) {
if(j-1 > i &&nums[j-1] == nums[j]){//这里的j-1大于i主要考虑的是我们去重复的是从
continue; //j开始指向的元素
}
int left = j+1;
int right = nums.size() - 1;
while(left < right) {
if(nums[i]+nums[j] > target - (nums[left]+nums[right])) right–;
else if(nums[i]+nums[j] < target - (nums[left]+nums[right])) left++;
else {
v.push_back(nums[i]);
v.push_back(nums[j]);
v.push_back(nums[left]);
v.push_back(nums[right]);
ans.push_back(v);
//去重处理
while(left < right && nums[right-1] == nums[right]) right–;
while(left > right && nums[left+1] == nums[left]) left++;
//换下一组
right–;
left++;
v.clear();
}
}
}
}
return ans;
}
};
class Solution {
public:
vector<vector> threeSum(vector& nums) {
/**
思路:
1.我们将所有元素进行升序处理(这样处理的话,我们可以知道当前面的元素大于0的时候,那么便一定
不会出现 a+b+c=0
2.这里我们设置三个指针(模拟的) 第一个指针(i)指向数组的第一个元素,第二个指针(left)指向数组的
第二个元素,第三个指针(right)指向数组的最后的元素
3.nums[i] + nums[left] + nums[right] > 0; right-- ,i和left不动
nums[i] + nums[left] + nums[right] < 0; left++,i和right不动
nums[i] + nums[left] + nums[right] = 0;left++,right–,i也移动一个单位
当我们找到一组答案的时候,就要同时移动三个指针;因为当我们找到一组答案的时候,如果不移动
i,只移动left和right,因为是升序的,那么的话nums[left] + nums[right] 只会更小
与nums[i]相加也不会等于0;如果我们想要最终的和为0,那么的话nums[i] < 0,nums[left] < 0,
nums[right] > 0,那么往后移动i,如果和为0的话 nums[left] + nums[right]的结果只会更小
因此我们每确定一组答案的时候,需要同时移动left,right,i
4.这里的去重,我们是当遇到相同的元素跳过它
*/
vector<vector >ans;
vectorv;
sort(nums.begin(),nums.end());
for(int i = 0; i < nums.size(); i++) {
if(nums[i] > 0){//如果首元素大于0的话那么就不会有和为0了
return ans;
}
if(i > 0 && nums[i] == nums[i-1]){
continue;
}
int left = i+1;
int right = nums.size() - 1;
while(left < right) {
int sum = nums[i] + nums[left] + nums[right];
if(sum > 0) right–;
else if(sum < 0) left++;
else {
v.push_back(nums[i]);
v.push_back(nums[left]);
v.push_back(nums[right]);
ans.push_back(v);
//去重处理(相邻的元素出现了重复)
while(left < right && nums[right-1] == nums[right]) right–;
while(left < right && nums[left+1] == nums[left]) left++;
//换下一组答案(上方的去重处理只是指针移动到最后一个重复的元素)
right–;
left++;
v.clear();
}
}
}
return ans;
}
};
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
/**
思路:
1.定义快慢指针(快指针一次移动一个节点,慢指针一次移动两个结点)
2.如果有环的话那么的话快慢指针一定会相遇(因为如果没环的话快慢指针永远不相遇)
3.那么我们接下来就要确认出口在哪里,(根据以证明的结论,定义一个新的结点头指针指向它,然后快指针
和其一块移动,当其相遇的时候,就是出口.
**/
ListNode* slowNode = head;
ListNode* fastNode = head;
//当fastNode->next != NULL的时候 是允许fastNode->next->next 为空的
//如果没有此条件的话,那么当指针指向最后一个结点的时候,fast->next 已经为空了,它便不能再指向空了
//即fast->next->next (不能空指向空)
while(fastNode != NULL && fastNode->next != NULL) {
fastNode = fastNode->next->next;
slowNode = slowNode->next;