leetcode: 链表题目2

文章目录

    • 160. Intersection of Two Linked Lists(相交链表的相交点)
    • 24. Swap Nodes in Pairs(成对交换链表节点)
    • 142. Linked List Cycle II(找到环的入口)
    • 445. Add Two Numbers II(将两个链表节点值相加)
    • 23. Merge k Sorted Lists(合并k个排序好的链表)

160. Intersection of Two Linked Lists(相交链表的相交点)

将两个链表合二为一,比如链表A、链表B,合并成两个链表A->B和B->A。

//解题思路:
// 将listB加到listA的后面、将listA也加到listB的后面,这样两个list等长
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* a_ptr = headA;
        ListNode* b_ptr = headB;
        
        while( a_ptr != b_ptr)
        {
            if(a_ptr == NULL)
                a_ptr = headB;
            else
                a_ptr = a_ptr->next;
            
            if(b_ptr == NULL)
                b_ptr = headA;
            else
                b_ptr = b_ptr->next;
        }
        return a_ptr;
    }
};

24. Swap Nodes in Pairs(成对交换链表节点)

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(head == NULL || head->next == NULL) return head;
        ListNode* pre = new ListNode(-1);
        ListNode* pre_next = NULL;
        ListNode* pre_next2 = NULL;
        ListNode* pre_next3 = NULL;
        ListNode* head_pre = pre;
        pre->next = head;
        while(pre->next && pre->next->next)
        {
            pre_next =  pre->next;
            pre_next2 = pre->next->next;
            pre_next3 = pre->next->next->next;
            
            pre_next->next = pre_next3;
            pre_next2->next = pre_next;
            pre->next = pre_next2;
            
            pre = pre->next->next;
            

        }  
        return head_pre->next;
    }
};

142. Linked List Cycle II(找到环的入口)

先用快慢指针判断是否是环,在用指针分别从head指针和快慢指针的交节点开始相交出就是环的入口推算见链表题

/**
 * 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)  return NULL; 
        
        //双指针判断是否有环
        ListNode *slow_ptr = head;
        ListNode *fast_ptr = head;
        bool bool_loop = false;
        while ( fast_ptr != NULL && fast_ptr->next != NULL && fast_ptr->next->next != NULL)
        {
            fast_ptr = fast_ptr->next->next;
            slow_ptr = slow_ptr->next;
            if ( fast_ptr == slow_ptr )
            {
                bool_loop = true;
                break;
            }
                
        }
        
        if (!bool_loop)
            return NULL;
        
        //有环找到环的入口
        ListNode *tmp_ptr = head;
        while ( tmp_ptr != slow_ptr )   //这里比较两个指针是否相等,应为val可能有相同的值
        {
            tmp_ptr = tmp_ptr->next;
            slow_ptr = slow_ptr->next;
        }
        
        return tmp_ptr;
    }
};

445. Add Two Numbers II(将两个链表节点值相加)

这个题目和题目1的区别是这个题目低位在最后。所以首先想到的是反转链表,但是另外一个思路是用两个栈,利用栈的先进后出。

/**
 * 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) return l2;
        if(l2 == NULL) return l1;        
        stack s1;          //用两个stack存储两个链表值再出栈计算
        stack s2;
        while(l1){
            s1.push(l1->val);
            l1 = l1->next;
        }
        while(l2){
            s2.push(l2->val);
            l2 = l2->next;
        } 
        int sum = 0;
        ListNode* res = NULL;
        ListNode* tmp = NULL;
        while(  !s1.empty() || !s2.empty()){
            if(!s1.empty()){
                sum+=s1.top();
                s1.pop();
            }
            if(!s2.empty()){
                sum+=s2.top();
                s2.pop();
            }
            tmp = new ListNode(sum%10);
            tmp->next = res;
            res = tmp;
            sum = sum/10;
        }    
        if(sum > 0){ //最后一位可能会需要进位
            tmp = new ListNode(sum);
            tmp->next = res;
            res = tmp;
        }        
        return res;
    }
};

23. Merge k Sorted Lists(合并k个排序好的链表)

利用一个优先队列进行排序

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeKLists(vector& lists) {
        auto cmp = [](ListNode*& cmpa, ListNode*& cmpb)
        {
            return cmpa->val > cmpb->val;
        };
        
        // 优先队列先将每个链表的head放到优先队列中排序
        priority_queue, decltype(cmp)> pri_queue(cmp);
        for(auto node : lists)  //将每个链表头指针也放到优先队列
        {
            if(node) pri_queue.push(node);
        }
        
        ListNode* dummy = new ListNode(-1);
        ListNode* cur = dummy;
        while(!pri_queue.empty())
        {
            auto p = pri_queue.top();
            pri_queue.pop();
            cur->next = p;
            cur = cur->next;
            if(cur->next) pri_queue.push(cur->next);  //如果最小的next存在,就将next放入优先队列排序
        }
        return dummy->next;
    }
};

你可能感兴趣的:(数据结构和算法)