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