1 链表逆序 206
遍历一个链表,建立一个新的链表节点,每次都往新的链表的头部插入, 就实现了逆序
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
ListNode *temp;
ListNode *ret = 0;
while(pHead){
temp = pHead->next;
pHead -> next = ret;
ret = pHead;
pHead = temp;
}
return ret;
}
};
2 将链表在位置m到n逆序 92
上一题的扩展,主要是想好 把三段给连起来,存一下相应的节点
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
ListNode *ret = 0;
ListNode *s = head; //存储一下开始指针
ListNode *pre_head = head;
ListNode *modify_tail = 0;
int i = 1;
while(head!=NULL){
if(i>=m && i <= n){
if(i == m){
modify_tail = head;
}
ListNode *temp = head->next;
head -> next = ret;
ret = head;
head = temp;
}else if(i < m){
pre_head = head;
head = head -> next;
}else{
break;
}
i++;
}
if(m == 1){ //当m从第一个开始逆序时,单独处理,不能返回s了,需要返回ret
modify_tail->next = head;
return ret;
}
pre_head->next = ret;
modify_tail->next = head;
return s;
}
};
3 求两个链表的结点 160
主要是求两个链表的长度,将链表对齐, 然后依次往后判断节点是否相同
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
lenA = self.get_len(headA)
lenB = self.get_len(headB)
if lenA > lenB:
for i in range(lenA - lenB):
headA = headA.next
if lenB > lenA:
for i in range(lenB - lenA):
headB = headB.next
while headA and headB:
if headA == headB:
return headA
headA = headA.next
headB = headB.next
return None
def get_len(self, head):
counter = 0
while head:
counter += 1
head = head.next
return counter
4 链表求环 ,相交节点 141 142
设置两个指针,fast slow fast每次走两步,slow每次一步,如果fast走到头了,还没有相遇则没有交点
如果相遇,记录此时的结点为meet, meet到环入口节点距离==head到入口节点距离
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
fast = slow = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
return True
return False
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *s = head;
ListNode *fast = head;
ListNode *slow = head;
ListNode *meet = 0;
while(fast){
fast = fast->next;
slow = slow -> next;
if(fast == NULL){
return NULL;
}
fast = fast->next;
if(fast == slow){
meet = slow;
break;
}
}
if(!meet){
return NULL;
}
while(slow != s){
slow = slow -> next;
s = s->next;
}
return s;
}
};
5 分割链表 86
题目:将小于某数的节点放到前面, 大于的放到后面
建立两个链表节点,遍历一次,小的往前面的链表加,大的往另一个链表上加 ,然后合并一下
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
ListNode bigger_head(0);
ListNode less_head(0);
ListNode *bigger = &bigger_head;
ListNode *less = &less_head;
ListNode *ret = less;
while(head!= NULL){
if(head->val >= x){
bigger -> next = head;
bigger = bigger -> next;
}else{
less -> next = head;
less = less -> next;
}
head = head -> next;
}
less -> next = bigger_head.next;
bigger -> next = NULL; // 必须手动指向空 不然一直超时
return ret->next;
}
};
6 复制还随机指针的链表,深度拷贝 138
就是比普通的链表多一个random指针,随机指
题目解读:指针里面存的是地址,深度拷贝的话,会产生新的地址的,不能用之前的地址指针了,必须建立一个映射保存一下原链表地址->节点位置的映射, 和 节点位置->新链表地址的映射 ,从而使两个链表相关联
class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head) {
map<RandomListNode *, int> node_int; //原链表地址->位置映射
vector<RandomListNode *> int_node;//位置->新链表地址映射 用vector就行
RandomListNode *p = head;
int i = 0;
while(p){
int_node.push_back(new RandomListNode(p->label));//保存两个映射
node_int[p] = i;
p = p ->next;
i ++;
}
int_node.push_back(0);
i = 0;
p = head;
while(p){
int_node[i]->next = int_node[i+1]; //next填充上
if(p->random){ // 因为空的没有对应序号 必须判断
int_node[i]->random = int_node[node_int[p->random]];//randonm填充
}
p = p -> next;
i++;
}
return int_node[0];
}
};
7 排序链表的合并 21
建立一个新的链表,遍历比较即可,不管那个长,把剩下的加到后面
class Solution:
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
ret = ListNode(0)
c = ret
while l1 != None and l2 != None:
if l1.val > l2.val:
ret.next = l2
l2 = l2.next
else:
ret.next = l1
l1 = l1.next
ret = ret.next
while l1 is not None:
ret.next = l1
ret = ret.next
l1 = l1.next
while l2 is not None:
ret.next = l2
l2 = l2.next
ret = ret.next
return c.next
8 合并K个有序链表 23
思路1:
拿到所有值到 list中 sort后,再连接起来 k链表n节点 复杂度 O(kn*log(kn))
思路2:
暴力合并, 前两个合并后再和第三个合并 再继续往下 k链表需要k-1次 n+2n+3n+(k-1)*n
思路3:
归并后合并 比如4个,前两个先合并,后两个合并,再合并一次 n*(k/2) + 2*n *(k/4) + ... + 2^log(k) * n / 2 ^ log(k) = 1/2(kn*log(k))
思路3代码
class Solution:
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
if len(lists) == 0:
return
if len(lists) == 1:
return lists[0]
if len(lists) == 2:
return self.mergeTwoLists(lists[0], lists[1])
mid = len(lists) // 2
sublist1 = lists[:mid]
sublist2 = lists[mid:]
node1 = self.mergeKLists(sublist1)
node2 = self.mergeKLists(sublist2)
return self.mergeTwoLists(node1, node2)
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
ret = ListNode(0)
c = ret
while l1 != None and l2 != None:
if l1.val > l2.val:
ret.next = l2
l2 = l2.next
else:
ret.next = l1
l1 = l1.next
ret = ret.next
while l1 is not None:
ret.next = l1
ret = ret.next
l1 = l1.next
while l2 is not None:
ret.next = l2
l2 = l2.next
ret = ret.next
return c.next