350. 两个数组的交集 II
复习知识点:本题对其中一个数组元素的出现次数进行记录,然后在下一个数组中查找每一个元素之于上一个数组的出现次数,当出现次数不为零的时候就将当前元素加入到结果数组中。
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
unordered_map<int, int> hash;
for(int num : nums1)
++hash[num];
vector<int> res;
for(int num : nums2)
{
// 如果当前数字有出现次数的话就将其加入到结果数组
// 当出现次数为0的话就将其擦除
if(hash.count(num))
{
res.push_back(num);
--hash[num];
// 次数减到0的时候擦除本数据
if(hash[num] == 0)
hash.erase(num);
}
}
return res;
}
};
234. 回文链表
复习知识点:本题第一个方法较为简单,将元素存储至数组中然后进行常规的双指针遍历。第二种方法较为复杂, 原地进行题目的求解,避免了额外空间的申请,首先使用快慢指针进行链表的分割,快指针一次走两步,慢指针一次走一步,慢指针最终会停留在中间位置,然后使用自定义反转链表的函数将后半段反转,使用反转后的头开始向后遍历,与之前的前半段进行比较,完成题目。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
// 该方法就是将链表放入数组然后双指针遍历,没啥好说的
// class Solution {
// public:
// bool isPalindrome(ListNode* head) {
// vector<int> tmp;
// while(head)
// {
// tmp.push_back(head -> val);
// head = head -> next;
// }
// int left = 0, right = tmp.size() - 1;
// while(left < right)
// {
// if(tmp[left] != tmp[right])
// {
// return false;
// }
// ++left;
// --right;
// }
// return true;
// }
// };
class Solution{
public:
bool isPalindrome(ListNode* head){
if(head == nullptr)
return true;
// 找到链表的后半部分,然后反转,然后前半部分后半部分对比
ListNode* before = findother(head);
// 从后半部分的头部开始反转后半部分
ListNode* tmp = reverselist(before -> next);
// 判断是否相等,分别从原来的表头和反转后的表头开始向后依次遍历
ListNode* p = head;
ListNode* q = tmp;
bool res = true;
while(p && q)
{
if(p -> val != q -> val)
return false;
p = p -> next;
q = q -> next;
}
return res;
}
// 反转链表
ListNode* reverselist(ListNode* head)
{
ListNode* pre = nullptr;
ListNode* cur = head;
while(cur)
{
// 从前往后依次反转即可
ListNode* nextnode = cur -> next;
cur -> next = pre;
pre = cur;
cur = nextnode;
}
return pre;
}
// 快慢指针将链表分为前后两部分
ListNode* findother(ListNode* head)
{
ListNode* slow = head;
ListNode* fast = head;
// 需要判断的是下一步是不是为空,因为快指针靠前,所以首先考虑快指针的后两个位置
while(fast -> next != nullptr && fast -> next -> next != nullptr)
{
slow = slow -> next;
fast = fast -> next -> next;
}
// slow就会停在中间位置的节点上
return slow;
}
};