0612
点这里
版本1:(没用虚拟头结点)
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
//ListNode* preHead = new ListNode(0, head);
ListNode* cur = head;
while(cur && cur->next){
//最少还剩两个节点
//两个结点值相等:就往后跳
if(cur->val == cur->next->val){
cur->next = cur->next->next;
}
else{
//两个结点值不相等
cur = cur->next;
}
}
return head;
}
};
版本2:(用了虚拟头结点)
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode* preHead = new ListNode(0, head);
ListNode* cur = preHead;
while(cur->next && cur->next->next){
//链表最少还剩两个结点:
//两个结点值相等:从第二个开始删除
if(cur->next->val == cur->next->next->val){
cur->next->next = cur->next->next->next;
}
else{
//两个结点值不相等:
cur = cur->next;
}
}
return preHead->next;
}
};
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode* preHead = new ListNode(0, head);
ListNode* cur = preHead;
while(cur->next && cur->next->next){
//链表最少还剩两个结点:
//两个结点值相等:循环删掉相同的结点
if(cur->next->val == cur->next->next->val){
int tmp = cur->next->val;
while(cur->next && cur->next->val == tmp){
cur->next = cur->next->next;
}
}
//两个结点值不相等:
else{
cur = cur->next;
}
}
return preHead->next;
}
};
剑指offer读书笔记4(面试题53-68)的第67题
class Solution {
public:
int myAtoi(string s) {
int n = s.size();
if(n == 0) return 0;
//空格:
int i = 0;
while(i < n && s[i] == ' '){
++i;
}
//符号位
char mark;
if(s[i] == '+' || s[i] == '-') mark = s[i++];
//数字
long num = 0;
while(i < n && s[i] >= '0' && s[i] <= '9'){
num = num * 10 + (s[i] - '0');
++i;
if(mark == '-'){
if(-num < INT_MIN)
return INT_MIN;
}
else{
if(num > INT_MAX)
return INT_MAX;
}
}
//返回
if(mark == '-') num = -num;
return (int)num;
}
};
dfs+回溯
相当于是深度优先遍历一个满二叉树,把满足左括号个数lc
和右括号个数rc
同时等于n的情况筛选出来,存到vector
中。
代码1:(这个比较好理解)
(题解见括号生成 | 深度优先遍历 | 最简洁易懂的题解 【c++/java版】)
class Solution {
vector<string> res;
string path;
int n;
public:
vector<string> generateParenthesis(int n) {
this->n = n;
dfs(0, 0);
return res;
}
private:
void dfs(int lc, int rc){
if(lc == n && rc == n){
//左右括号的个数都刚刚好够
res.push_back(path);
return;
}
if(lc < n){
//左括号个数还没够
path.push_back('(');
dfs(lc + 1, rc);
path.pop_back();
}
if(rc < n && rc < lc){
//右括号个数还没够并且少于左括号的个数
path.push_back(')');
dfs(lc, rc + 1);
path.pop_back();
}
}
};
代码2:
(题解见虽然不是最秀的,但至少能让你看得懂!下面的评论)
class Solution {
vector<string> res;
string path;
public:
vector<string> generateParenthesis(int n) {
//if(n == 0) return {};
dfs(0, 0, n);
return res;
}
private:
void dfs(int left, int right, int n){
if(left > n || right > left) return;//right > n || left > right
if(path.size() == n * 2){
res.push_back(path); return; }
path.push_back('(');
dfs(left + 1, right, n);
path.pop_back();
path.push_back(')');
dfs(left, right + 1, n);
path.pop_back();
}
};
题解见下一个排列算法详解:思路+推导+步骤,看不懂算我输!,代码见它下面的评论。
思路:
从后往前遍历,遇到一个数nums[i]
比它前面的数nums[i - 1]
大,
对从这个数开始到数组结束的部分进行排序,
然后遍历这部分内容,找到第一个比nums[i - 1]
大的数nums[j]
,把二者交换,然后return;
如果遍历完整个数组都没有遇到一个数nums[i]
比它前面的数nums[i - 1]
大的情况,就说明这个数组是降序的,对它进行排序,然后return;
代码:
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int n = nums.size();
for(int i = n - 1; i > 0; --i){
//找到一个比它前面一个数大的数:
if(nums[i] > nums[i - 1]){
//迭代器:
//auto it = nums.end();
vector<int>::iterator it = nums.end();
//从nums.end()开始倒着走n - i步:找到指向nums[i]的迭代器
for(int k = 0; k < n - i; ++k) --it;
//排序:
sort(it, nums.end());
//找到第一个比nums[i - 1]大的数:
for(int j =