数组
双指针用的比较多
- 704. 二分查找
- 27. 移除元素
- 977. 有序数组的平方
- 209. 长度最小的子数组
滑动窗口 - 59. 螺旋矩阵 II
!! 需要再复习
class Solution {
public:
int search(vector<int>& nums, int target) {
// int left = 0;
// int right = nums.size()-1;
// while(left<=right) {
// int mid = left+(right-left)/2;
// if(nums[mid] > target) {
// right = mid-1;
// }
// else if(nums[mid] < target) {
// left = mid+1;
// }
// else
// return mid;
// }
// return -1;
//for循环就不用指定i++ j--了,在if判断中已经添加了对i j 的处理
for(int i=0,j=nums.size()-1;i<=j;) {
int mid = i+((j-i)/2);
if(nums[mid]==target)
return mid;
else if(nums[mid]<target) {
i=mid+1;
}
else if(nums[mid]>target) {
j=mid-1;
}
}
return -1;
}
};
快慢指针,一遍过
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int i,j=0;
for(i=0;i<nums.size();i++) {
if(nums[i]!=val) {
nums[j]=nums[i];
j++;
}
if(nums[i]==val) {
continue;
}
}
return j;
}
};
借助sort
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
for(int i=0;i<nums.size();i++) {
nums[i]*=nums[i];
}
sort(nums.begin(),nums.end());
return nums;
}
};
不用sort
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int k=nums.size()-1;
vector<int> res(nums.size(),0);
//原先的数组是非递减顺序,遇到绝对值大的负值 平方后会改变位置
//使用双指针控制存入新数组的大小顺序
for(int i=0,j=nums.size()-1;i<=j) {
if(nums[i]*nums[i] < nums[j]*nums[j]){
res[k] = nums[j]*nums[j];
k--;
j--;
}
else {
res[k] = nums[i]*nums[i];
k--;
i++;
}
}
return res;
}
};
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int i=0,j=0;
int sum=0;
int count=nums.size()+1;
for(int i=0,j=0;i<nums.size();i++) {
sum+=nums[i];
while(sum>=target) {
count = count < (i-j+1) ? count : (i-j+1);
sum-=nums[j++];
}
}
return count == nums.size()+1 ? 0 : count;
}
};
59. 螺旋矩阵 II
!!
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n, 0)); // 使用vector定义一个二维数组
int startx = 0, starty = 0; // 定义每循环一个圈的起始位置
int loop = n / 2; // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理
int mid = n / 2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
int count = 1; // 用来给矩阵中每一个空格赋值
int offset = 1; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
int i,j;
while (loop --) {
i = startx;
j = starty;
// 下面开始的四个for就是模拟转了一圈
// 模拟填充上行从左到右(左闭右开)
for (j; j < n - offset; j++) {
res[i][j] = count++;
}
// 模拟填充右列从上到下(左闭右开)
for (i; i < n - offset; i++) {
res[i][j] = count++;
}
// 模拟填充下行从右到左(左闭右开)
for (; j > starty; j--) {
res[i][j] = count++;
}
// 模拟填充左列从下到上(左闭右开)
for (; i > startx; i--) {
res[i][j] = count++;
}
// 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
startx++;
starty++;
// offset 控制每一圈里每一条边遍历的长度
offset += 1;
}
// 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
if (n % 2) {
res[mid][mid] = count;
}
return res;
}
};
链表
大部分的题来说,定义一个虚拟头节点能够有助于处理链表操作。
删除操作大多需要pre来保存前一节点的状态
环形链表这个题时间长又忘了怎么解了
- 203. 移除链表元素
- 707. 设计链表
此题不熟 - 206. 反转链表
头插法 - 19. 删除链表的倒数第 N 个结点
①记录链表长度,找到倒数第n个节点的下标
②pre 和 cur - 面试题 02.07. 链表相交
①统计两链表的长度
②统一长度后两链表一起遍历判断节点是否相等 - 142. 环形链表 II
!!! 快慢指针,时间久又有点忘记了。
203. 移除链表元素
①虚拟头结点dummyHead;
②用一temp来遍历链表所有节点
③链表删除节点的逻辑…太熟了不写了
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* temp = dummyHead;
while(temp->next != NULL) {
if(temp->next->val == val) {
ListNode* node = temp->next;
temp->next = temp->next->next;
delete node;
} else {
temp = temp->next;
}
}
head = dummyHead->next;
delete dummyHead;
return head;
}
};
707. 设计链表
此题不熟
class MyLinkedList {
public:
struct LinkedNode {
int val;
LinkedNode* next;
LinkedNode(int val):val(val),next(nullptr) {}
};
MyLinkedList() {
_dummyHead = new LinkedNode(0);
_size=0;
}
int get(int index) {
if(index > (_size-1) || index < 0)
return -1;
LinkedNode* cur = _dummyHead->next;
while(index--) {
cur = cur->next;
}
return cur->val;
}
void addAtHead(int val) {
LinkedNode* node = new LinkedNode(val);
node->next = _dummyHead->next;
_dummyHead->next = node;
_size++;
}
void addAtTail(int val) {
LinkedNode* node = new LinkedNode(val);
LinkedNode* cur = _dummyHead;
while(cur->next!=nullptr) {
cur = cur->next;
}
cur->next = node;
_size++;
}
void addAtIndex(int index, int val) {
if(index > _size)
return;
if(index < 0)
index=0;
LinkedNode* node = new LinkedNode(val);
LinkedNode* cur = _dummyHead;
while(index--) {
cur = cur->next;
}
node->next = cur->next;
cur->next = node;
_size++;
}
void deleteAtIndex(int index) {
if(index >= _size || index<0)
return;
LinkedNode* cur = _dummyHead;
while(index--) {
cur = cur->next;
}
LinkedNode* node = cur->next;
cur->next = cur->next->next;
delete node;
node = nullptr;
_size--;
}
private:
int _size;
LinkedNode* _dummyHead;
};
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList* obj = new MyLinkedList();
* int param_1 = obj->get(index);
* obj->addAtHead(val);
* obj->addAtTail(val);
* obj->addAtIndex(index,val);
* obj->deleteAtIndex(index);
*/
206. 反转链表
头插法
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = nullptr;
ListNode* cur = head;
while(cur!=nullptr) {
ListNode* node = new ListNode(0);
node->val = cur->val;
node->next = dummyHead->next;
dummyHead->next = node;
cur = cur->next;
}
return dummyHead->next;
}
};
19. 删除链表的倒数第 N 个结点
①记录链表长度,找到倒数第n个节点的下标
②pre 和 cur
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
if(head == nullptr)
return head;
else if(head->next==nullptr && n==1)
return nullptr;
ListNode* tail = head;
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
int size = 0;
while(tail!=nullptr) {
tail = tail->next;
size++;
}
ListNode* cur = head;
ListNode* pre = dummyHead;
pre->next = cur;
int a = size-n;
while(a-- && cur!=nullptr) {
pre = cur;
cur = cur->next;
}
ListNode* temp = cur;
pre->next = cur->next;
delete temp;
return dummyHead->next;
}
};
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* curA = headA;
ListNode* curB = headB;
int sizeA = 0, sizeB = 0;
while(curA!=nullptr) {
sizeA++;
curA = curA->next;
}
while(curB!=nullptr) {
sizeB++;
curB = curB->next;
}
curA = headA;
curB = headB;
if(sizeA > sizeB) {
int a = sizeA - sizeB;
while(a--) {
curA=curA->next;
}
}
else if(sizeA < sizeB) {
int b = sizeB - sizeA;
while(b--) {
curB=curB->next;
}
}
while(curA != nullptr && curB != nullptr)
{
if(curA == curB)
return curA;
else
{
curA = curA->next;
curB = curB->next;
}
}
return nullptr;
}
};
142. 环形链表 II
快慢指针,时间久又有点忘记了。
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
while(fast!=nullptr && fast->next!=nullptr) {
slow = slow->next;
fast = fast->next->next;
if(slow == fast) {
ListNode* index1 = head;
ListNode* index2 = fast;
while(index1!=index2) {
index1 = index1->next;
index2 = index2->next;
}
return index2;
}
}
return nullptr;
}
};