19.删除链表的倒数第n个节点
1.计算长度,两次遍历
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
int count=1;
ListNode* temp=head;
while(temp->next!=nullptr){
temp=temp->next;
count++;
}
if(count-n==0){
return head->next;
}
else{
temp=head;
for(int i=0;i<count-n-1;i++){
temp=temp->next;
}
temp->next=temp->next->next;
return head;
}
}
};
2.双指针法
初始:慢指针指向头结点的前一位,快指针指向头结点
快指针先找到距离慢指针n的节点
然后两者一起往后遍历,直到快指针为空,慢指针节点的next删除即可
返回头结点前一位的next;
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummy=new ListNode(0,head);
ListNode* first=head;
ListNode* second=dummy;
for(int i=0;i<n;++i){
first=first->next;
}
while(first){
first=first->next;
second=second->next;
}
second->next=second->next->next;
ListNode* ans=dummy->next;
delete dummy;
return ans;
}
};
3.用栈
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummy = new ListNode(0, head);
stack<ListNode*> stk;
ListNode* cur = dummy;
while (cur) {
stk.push(cur);
cur = cur->next;
}
for (int i = 0; i < n; ++i) {
stk.pop();
}
ListNode* prev = stk.top();
prev->next = prev->next->next;
ListNode* ans = dummy->next;
delete dummy;
return ans;
}
};
22.括号生成
回溯法
class Solution {
public:
void backtrack(int open,int close,vector<string> &res,string &cur,int n){
if (cur.size() == n * 2) {
res.push_back(cur);
return;
}
if (open < n) {
cur.push_back('(');
backtrack(open+1,close,res,cur, n);
cur.pop_back();
}
if (close < open) {
cur.push_back(')');
backtrack(open,close+1,res,cur, n);
cur.pop_back();
}
}
vector<string> generateParenthesis(int n) {
vector<string> res;
string cur;
backtrack(0,0,res,cur,n);
return res;
}
};
31.下一个排列
找到一个靠右的较大数,找到一个靠右的较小数,两者交换,重排较大数位置之后的数。
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int i=nums.size()-2;
while(i>=0&&nums[i]>=nums[i+1]){
i--;
}
if(i>=0){
int j=nums.size()-1;
while(j>=0&&nums[i]>=nums[j]){
j--;
}
swap(nums[i],nums[j]);
}
reverse(nums.begin()+i+1,nums.end());
}
};