class Solution {
public:
bool isFlipedString(string s1, string s2) {
if(s1.size() != s2.size()) return false;
if(s1.size() == s2.size() & s1.size() == 0) return true;
string s3;
s3 = s2;
s3 += s2;
int n;
if(n = s3.find(s1) != string::npos)
return true;
else
return false;
}
};
总结:新增字符串为两个s2结合,如果s3中有s1子串就返回true;
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeDuplicateNodes(ListNode* head) {
if(head == NULL || head->next == NULL) return head;
//使用哈希表
unordered_set<int>uSet;
ListNode *rear = head->next;
ListNode *prev = head;
uSet.insert(head->val);
while(rear)
{
if(!uSet.count(rear->val))
{
uSet.insert(rear->val);
prev->next = rear;
prev = prev->next;
}
rear = rear->next;
}
prev->next = NULL;
return head;
}
};
总结:本题中由于要删除重复的节点,所以我们很容易想到C++中hash表,就对弈STL unordered_set, 然后遍历链表,使用前后指针。有发现重复的元素就一直向前移动。当没有出现重复的元素时,前驱指针先移动,最后在后继指针next置空,这样可以处理尾结点以及防止某处后面全为重复节点
三、返回链表倒数第K个节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
int kthToLast(ListNode* head, int k) {
//双指针。先走K步,然后再让后驱跟前指针一起走。
if(head == NULL) return 0;
ListNode *prev = head;
while(k)
{
prev = prev->next;
k--;
}
while(prev)
{
head = head->next;
prev = prev->next;
}
return head->val;
}
};
总结:本题思路前后指针,前指针先走K,然后后指针(头)与前指针一起走,后指针到了K就前指针到了倒数第K个节点
四、删除链表某个节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void deleteNode(ListNode* node) {
if(node == NULL) return;
ListNode *mov = node;
ListNode *prev = mov->next;;
while(prev)
{
mov->val = prev->val;
if(prev->next != NULL) mov = mov->next;
prev = prev->next;
}
mov->next = NULL;
}
};
总结:使用两个指针一直后面值赋值到前面即可,注意mov不可走到尾节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
if(head == NULL || head->next == NULL) return head;
//出题人语文是数学老师教的,按照题意的话,可以使用多的空间,以X为头,进行大于头插,小于尾插。
//解法2:对链表进行分大小
ListNode *bigHead = new ListNode(0);
ListNode *littleHead = new ListNode(0);
ListNode *tmp1 = bigHead;
ListNode *tmp2 = littleHead;
while(head)
{
//比较大小
if(head->val >= x)
{
tmp1->next = head;
tmp1 = tmp1->next;
}
else
{
tmp2->next = head;
tmp2 = tmp2->next;
}
//头移动
head = head->next;
}
//重组链表
tmp2->next = bigHead->next;
tmp1->next = NULL;
return littleHead->next;
}
};
总结:若遇到分类题目及可以使用双百法。还有另外一种思路,在注释中
六、链表求和
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* L1, ListNode* L2) {
if(L1 == NULL || L2 == NULL) return NULL;
//要注意有进位的情况
ListNode *head = new ListNode(0);
head->next = NULL;
ListNode *tmp = head;
int sum;
int num;
int carryBit = 0;
int v1, v2;
//可能存在两个链表长度不相等的情况
while(L1 != NULL || L2 != NULL)
{
v1 = (L1 == NULL) ? 0 : L1->val;
v2 = (L2 == NULL) ? 0 : L2->val;
//两数相加加进位
sum = v1 + v2 + carryBit;
num = sum > 9 ? (sum % 10) : sum;
//取得进位
carryBit = sum > 9 ? 1 : 0;
ListNode *node = new ListNode(num);
tmp->next = node;
node->next = NULL;
tmp = tmp->next;
if(L1) L1 = L1->next;
if(L2) L2 = L2->next;
}
//收尾处理
if(carryBit == 1)
{
ListNode *node = new ListNode(carryBit);
tmp->next = node;
node->next = NULL;
}
return head->next;
}
};
总结:直接相加,判断进位,最后结束要判断是否有进位。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
//找中间翻转再比较。学到了,找中间的方法,让前指针走两倍,后指针走一下
//空串和1个位回文。。
if(head == NULL || head->next == NULL) return true;
ListNode *first = head;
ListNode *slow = head;
//快慢指针找中点
while(first && first->next)
{
slow = slow->next;
first = first->next->next;
}
//逆序前半段
ListNode *cur = head;
ListNode *tmp;
while(cur->next != slow)
{
tmp = cur->next;
cur->next = tmp->next;
tmp->next = head;
head = tmp;
}
//判断奇数偶数
while(slow)
{
//偶数时
if(first == NULL)
{
if(slow->val == head->val)
{
head = head->next;
slow = slow->next;
}
else
{
return false;
}
}
else if(first->next == NULL)
{
if(slow->next->val == head->val)
{
head = head->next;
slow = slow->next;
}
else
{
return false;
}
if(slow->next == NULL)
break;
}
}
return true;
}
};
总结:找到中间位置,前后指针,一个走两个一个走一个,当前面的指针到达尾部就找到了中间位置。然后再进行翻转前面的链表。之后比较。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headA == NULL || headB == NULL ) return NULL;
ListNode *a = headA;
ListNode *b = headB;
//快慢指针
while(a != b)
{
a = a == NULL ? headA : a->next;
b = b == NULL ? headB : b->next;
}
return a;
}
};
总结:双指针长度消差法
### 解题思路
此处撰写解题思路
### 代码
```cpp
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
//快慢指针
if(head == NULL || head->next == NULL) return NULL;
ListNode *fast = head;
ListNode *slow = head;
bool sign = false;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
{
sign = true;
break;
}
}
if(!sign) return NULL;
//此时已经有
slow = head;
while(slow != fast)
{
slow = slow->next;
fast = fast->next;
}
return slow;
}
};
总结:C++快慢指针
class MinStack {
//两个辅助栈
private:
stack<int>mainStack;
stack<int>helpStack;
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
mainStack.push(x);
if(helpStack.empty()) helpStack.push(x);
else
{
//当辅助栈第一个元素大于X则X进栈
if(helpStack.top() > x) helpStack.push(x);
else
{
int tmp = helpStack.top();
helpStack.push(tmp);
}
}
}
void pop() {
mainStack.pop();
helpStack.pop();
}
int top() {
return mainStack.top();
}
int getMin() {
return helpStack.top();
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(x);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
总结:C++使用两个栈来实现