// 时间复杂度 O(n)
// 空间复杂度 O(1)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slow = 0;
int fast = 0;
int n = nums.size();
while(fast < n){
if(nums[fast] != val){
swap(nums[slow++],nums[fast]);
}
fast++;
}
return slow;
}
};
// 时间复杂度 O(n)
// 空间复杂度 O(1)
class Solution {
public:
void reverseString(vector<char>& s) {
for(int i =0,j=s.size()-1;i < j;i++,j--){
swap(s[i],s[j]);
}
}
};
// 时间复杂度O(n)
// 空间复杂度O(n)
class Solution {
public:
string replaceSpace(string s) {
int count = 0;
int oldSize = s.size();
for(char& c:s){
if(c == ' ')count++;
}
s.resize(oldSize+count*2);
int newSize = s.size();
// "We are happy ."
// i j
// %20
// i越界之前,j肯定可以追上,从而终止循环。
for(int i = oldSize-1,j=newSize-1;i < j;i--,j--){
if(s[i] != ' '){
s[j] = s[i];
}else{
s[j]='0';
s[j-1]='2';
s[j-2]='%';
j -= 2;
}
}
return s;
}
};
// 时间复杂度O(n)
// 空间复杂度O(1)
class Solution {
public:
// 左闭右闭
void myReverse(string& s,int begin,int end){
for(int i =begin,j=end;i<j;i++,j--){
swap(s[i],s[j]);
}
}
void delExtraSpace(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) {
delExtraSpace(s);
myReverse(s,0,s.size()-1);
int slow = 0;
for(int i = 0;i <= s.size();i++){
if(i == s.size() || s[i] == ' '){
myReverse(s,slow,i-1);// 到空格了,其那面是单词
slow = i+1;
}
}
return s;
}
};
// 时间复杂度 O(n)
// 空间复杂度 O(1)
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* tmp;
ListNode* pre = nullptr;// 想下可以理解,调转过来,第一个结点的next为nullpter
ListNode* cur = head;
while(cur){
tmp = cur->next;// 保存下一个结点
cur->next = pre;
pre = cur;// 当前结点为下一个的next
cur = tmp;// 当前结点变为next
}
return pre;
}
};
// 时间复杂度O(n)
// 空间复杂度O(1)
class Solution {
public:
ListNode* dfs(ListNode* cur,ListNode* pre){
if(cur == nullptr)return pre;
ListNode* tmp = cur->next;
cur->next = pre;
// pre = cur; 直接在下面传cur即可
return dfs(tmp,cur);
}
ListNode* reverseList(ListNode* head) {
return dfs(head,nullptr);
}
};
// 时间复杂度O(n)
// 空间复杂度O(1)
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* tmpHead = new ListNode(0);
tmpHead->next = head;
ListNode* fast = tmpHead;
ListNode* slow = tmpHead;
n++;// 因为要删除结点,所以要停在目标结点前。fast先走n+1步
while(fast && n--){
fast = fast->next;
}
while(fast){
fast = fast->next;
slow = slow->next;
}
ListNode* tmp = slow->next;
slow->next = tmp->next;
delete tmp;
return tmpHead->next;
}
};
// 时间复杂度O(n)
// 空间复杂度O(1)
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int lenA = 0;
int lenB = 0;
ListNode* curA = headA;
ListNode* curB = headB;
while(curA){
lenA++;
curA = curA->next;
}
while(curB){
lenB++;
curB = curB->next;
}
// 默认A为更长的
if(lenB > lenA){
swap(headA,headB);
swap(lenA,lenB);
}
int dis = lenA - lenB;
curA = headA;
curB = headB;
while(dis-- && curA){
curA = curA->next;
}
// 同一个起跑线
while(curA){
if(curA == curB)return curA;
curA = curA->next;
curB = curB->next;
}
return NULL;
}
};
// 时间复杂度 O(n)
// 空间复杂度 O(1)
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* slow = head;
ListNode* fast = head;
while(fast && fast->next){
slow = slow->next;
fast = fast->next->next;
if(slow == fast){
ListNode* tmp = head;
while(tmp != fast){
tmp = tmp->next;
fast = fast->next;
}
return fast;
}
}
return NULL;
}
};
// 时间复杂度 O(n²)
// 空间复杂度 O(n)
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>>ret;
sort(nums.begin(),nums.end());
int n = nums.size();
for(int i = 0;i < n;i++){// a=nums[i]
if(nums[i] > 0)break;// 去掉无意义的计算
if(i > 0 && nums[i] == nums[i-1]){// a去重
continue;
}
int left = i+1;
int right = n-1;
while(left < right){
int tmpSum = nums[i]+nums[left]+nums[right];
if(tmpSum > 0)right--;
else if(tmpSum < 0)left++;
else{
// 收集结果
ret.push_back({nums[i],nums[left],nums[right]});
// 去重
// left ->left right<-right
while(left < right && nums[left] == nums[left+1])left++;
while(left < right && nums[right] == nums[right-1])right--;
// 经过上述两个循环后,left right分别指向最后一个与上面收集结果时候相等的元素,经过下面再次++后,指向第一个与上述结果不相等我两个元素。
// 收缩-调整位置
left++;
right--;
}
}
}
return ret;
}
};
// 时间复杂度O(n²)
// 空间复杂度O(n)
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>>ret;
sort(nums.begin(),nums.end());
int n = nums.size();
for(int i = 0;i < n;i++){// a=nums[i]
if(nums[i] > 0)break;// 去掉无意义的计算
if(i > 0 && nums[i] == nums[i-1]){// a去重
continue;
}
unordered_set<int>set;
for(int j = i+1;j < n;j++){// b=nums[j]
if(j > i + 2 &&
nums[j] == nums[j-1] &&
nums[j-1] == nums[j-2]){// b去重
continue;
}
int c = 0 - nums[i] - nums[j];// c
if(set.find(c) != set.end()){// 找到了
ret.push_back({nums[i],nums[j],c});
set.erase(c);// c去重
}else{// 没找到
set.emplace(nums[j]);
}
}
}
return ret;
}
};
// 时间复杂度O(n³)
// 空间复杂度O(n)
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>>ret;
sort(nums.begin(),nums.end());
int n = nums.size();
for(int i = 0;i < n;i++){// a = nums[i]
if(nums[i] > target && nums[i] >= 0)break;// 剪枝,去掉无意义计算
if(i > 0 && nums[i] == nums[i-1])continue;// 去重
for(int j = i+1; j < n;j++){// b = nums[j]
if(nums[i] + nums[j] > target &&
nums[i]+ nums[j] >= 0){// 剪枝,去掉无意义计算
continue;
}
if( j > i + 1 && nums[j] == nums[j-1])continue;// b去重
int left = j + 1;
int right = n-1;
while(left < right){
// 防止溢出,转long
long tmpSum = (long)nums[i] + nums[j] + nums[left] + nums[right];
if(tmpSum > target)right--;
else if(tmpSum < target)left++;
else{// 收集结果
ret.push_back({nums[i],nums[j],nums[left],nums[right]});
while(left < right && nums[left] == nums[left+1])left++;
while(left < right && nums[right] == nums[right-1])right--;
right--;
left++;
}
}
}
}
return ret;
}
};