题目
1.力扣160. 相交链表
2.141. 环形链表
3.142. 环形链表 II
4. 86. 分隔链表
思路与算法
- 160相交链表:两种方法,直观的就是set存值,将set中存入一个表的指针,然后遍历另一个表,如果存到相同的set,那么该点就是这个交点。亦或者用另一种方法,将长短链表对齐,将长链表和短链表的尾巴对齐,头部也移动至对齐,然后开始同步后移指针,当指针所指的节点相同时,即为那个相交点,本题很简单,但是也很基础,注意理解。
- 141和142的解答是基本一致的,我们只需要使用上一题的set的思想,依次将节点加入set,如果set中已经出现head,则返回head。141是返回true,142返回当前节点即可,思路一致。
- 86分隔链表的这个题主要是找两个dummy头,分别将对应的节点领走。大于x的跟一个dummy头,小于的跟另一个,最后再连接起来即可。
代码实现
160相交链表:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
HashSet<ListNode> set = new HashSet<>();
while(headA != null){
set.add(headA);
headA = headA.next;
}
while (headB != null) {
if (set.contains(headB)) {
return headB;
}
headB = headB.next;
}
return null;
}
}
/**
* 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) {
// 新建空指针
ListNode *head = NULL;
// 先对齐两个链表
int lenA = getLength(headA);
int lenB = getLength(headB);
if (lenA >= lenB) {
headA = Formulation(lenA,lenB,headA);
} else {
headB = Formulation(lenB,lenA,headB);
}
// 再同时移动指针直到指向的地址相同为止,此时返回结果即可
while(headA && headB) {
if (headA == headB) {
return headA;
}
headA = headA->next;
headB = headB->next;
}
return NULL;
}
// 计算链表长度
int getLength(ListNode *head) {
int res = 0;
while(head) {
res++;
head = head->next;
}
return res;
}
// 让长链表与短链表对齐
ListNode *Formulation(int long_len,int short_len,ListNode *head) {
int differ = long_len - short_len;
while(differ && head) {
head = head->next;
differ--;
}
return head;
}
};
- 环形链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
std::set<ListNode*> node_set;
while(head) {
if(node_set.find(head) != node_set.end()) {
return true;
}
node_set.insert(head);
head = head->next;
}
return false;
}
};
- 环形链表 II
/**
* 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) {
std::set<ListNode*> node_set;
while(head) {
if(node_set.find(head) != node_set.end()) {
return head;
}
node_set.insert(head);
head = head->next;
}
return NULL;
}
};
86分隔链表
/**
* 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) {
// 临时的两个头结点并新建两个指针指向这两个头结点
ListNode l_head(0);
ListNode m_head(0);
ListNode* l_ptr = &l_head;
ListNode* m_ptr = &m_head;
// 遍历,把比x大的节点放在m_head之后,小的放在l_head之后
while(head){
if(head->val >= x) {
m_ptr->next = head;
m_ptr = head;
} else {
l_ptr->next = head;
l_ptr = head;
}
head = head->next;
}
l_ptr->next = m_head.next;
m_ptr->next = NULL;
return l_head.next;
}
};
写在最后
冲!