20200908:链表类题目集合上

链表类题目集合上

题目

1.力扣160. 相交链表
在这里插入图片描述
2.141. 环形链表
在这里插入图片描述
3.142. 环形链表 II
在这里插入图片描述
4. 86. 分隔链表

在这里插入图片描述

思路与算法

  1. 160相交链表:两种方法,直观的就是set存值,将set中存入一个表的指针,然后遍历另一个表,如果存到相同的set,那么该点就是这个交点。亦或者用另一种方法,将长短链表对齐,将长链表和短链表的尾巴对齐,头部也移动至对齐,然后开始同步后移指针,当指针所指的节点相同时,即为那个相交点,本题很简单,但是也很基础,注意理解。
  2. 141和142的解答是基本一致的,我们只需要使用上一题的set的思想,依次将节点加入set,如果set中已经出现head,则返回head。141是返回true,142返回当前节点即可,思路一致。
  3. 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;
    }
};
  1. 环形链表
/**
 * 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;
    }
};
  1. 环形链表 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;
    }
};

写在最后

冲!

猜你喜欢

转载自blog.csdn.net/qq_36828395/article/details/108479933