马上要面试了,把前些天在LeetCode上刷的题再看一遍。
写上注释,算复习了,也方便以后复习。
带 * 号的为忘记怎么做的。
21. 206. 反转链表(链表模拟)
class Solution {
public:
ListNode* reverseList(ListNode* head) {
// 翻转链表不需要虚拟头结点
ListNode *pre = NULL, *cur = head, *post;
// 赋值操作成环
while (cur != NULL) {
post = cur->next;
cur->next = pre;
pre = cur;
cur = post;
}
return pre;
}
};
22. 92. 反转链表 II(链表模拟)
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
// 附加头结点
ListNode *dummyHead = new ListNode(0);
dummyHead->next = head;
// 翻转时使用
ListNode *pre = dummyHead, *cur = head, *post;
// 记录翻转边界
ListNode *left, *right;
// 计数
int count = 1;
// 第一步,找到左边界
while (count < m) {
pre = pre->next;
cur = cur->next;
count ++;
}
// 此时,cur指向m号,令left指向m-1号
left = pre;
// 第二步,找到右边界,并进行翻转
while (count <= n) {
post = cur->next;
cur->next = pre;
pre = cur;
cur = post;
count ++;
}
// 此时,cur指向n+1号,[m..n]完成翻转,令right指向n号
right = pre;
// 第三步,进行连接(left与right可能相等)
left->next->next = cur;
left->next = right;
// 执行返回
ListNode *retHead = dummyHead->next;
delete dummyHead;
return retHead;
}
};
23. 83. 删除排序链表中的重复元素(链表模拟)
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
// 建立附加头结点
ListNode *dummyHead = new ListNode(0);
dummyHead->next = head;
// 删除时使用的指针
ListNode *pre = dummyHead, *cur = dummyHead->next;
// 处理开始,比较cur与cur->next的data域,若相等,删除cur
while (cur && cur->next != NULL) {
if (cur->val == cur->next->val) {
pre->next = cur->next;
delete cur;
cur = pre->next;
}
else {
pre = pre->next;
cur = cur->next;
}
}
// 返回
ListNode *retHead = dummyHead->next;
delete dummyHead;
return retHead;
}
};
24. 26. 删除排序数组中的重复项(简单数组)
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int n = nums.size();
if (n == 0) return 0;
if (n == 1) return 1;
int i = 0, j = 1;
while (j < n) {
// 一样就跳过
while (j < n && nums[j] == nums[i]) j++;
// 不一样就加入
if (j < n) nums[++i] = nums[j++];
}
return i + 1;
}
};
25. 80. 删除排序数组中的重复项 II(简单数组+状态机)
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int n = nums.size();
if (n == 0) return 0;
// [0..i]为最后剩余,[0..j)已经被处理
int i = 0, j = 1;
// 1:A 2:AA
int type = 1;
while (j < n) {
// 类型1可能转为类型2,无论如何都会收下第j个
if (type == 1) {
if (nums[i] == nums[j]) {
type = 2;
}
nums[++i] = nums[j++];
}
// 类型2可能转为类型1,此时要收下第j个
// 否则循环,直到可以转为类型1
else {
while (j < n && nums[i] == nums[j]) j++;
if (j < n) {
nums[++i] = nums[j++];
type = 1;
}
}
}
return i + 1;
}
};