leetcode brush questions (3)

Hello friends, today is the third article of my leedcode brushing series, let's not talk nonsense, let's go directly to the topic.

split linked list

Leetcode split linked list (difficulty: medium)

Topic requirements

Given a head node head of a linked list and a specific value x, please divide the linked list so that all nodes less than x appear before nodes greater than or equal to x.

You don't need to preserve the initial relative positions of the nodes in each partition.

use case input

Example 1:
insert image description here
Input: head = [1,4,3,2,5,2], x = 3
Output: [1,2,2,4,3,5]

Example 2:
Input: head = [2,1], x = 2
Output: [1,2]

This is the interface provided by the topic

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* partition(struct ListNode* head, int x){
    
    

}

hint

hint:

The number of nodes in the linked list is in the range [0, 200]
-100 <= Node.val <= 100
-200 <= x <= 200

Question ideas

We can use a pointer to traverse the linked list. When we encounter a number smaller than x, we place it on the left side, and nodes greater than or equal to it on the right side. Finally, we use a pointer to connect these two parts to get That's the result we need.

insert image description here
Define four structure pointers: bs and be point to the head and tail of the linked list less than x respectively, as and ae point to the head and tail of the linked list greater than or equal to x respectively.
insert image description here
insert image description here
Continue this action until cur equals NULL.
insert image description here
Then we connect these two parts with pointers. And manually set ae to NULL to prevent an infinite loop in the linked list.
insert image description here
After we are done, we still need to pay attention to: when there are only values ​​smaller than x or only parts larger than x, our above idea will not work. We need to make a judgment. When bs is NULL, we can directly return as , because even if as is also NULL, the returned value is also NULL. When as is NULL, we directly return bs without setting ae to NULL.

C language code implementation

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* partition(struct ListNode* head, int x){
    
    
//定义四个结构体指针来管理小于和大于等于x两部分的链表
	//小于x部分的头节点
    struct ListNode* bs = NULL;
    //小于x部分的尾节点
    struct ListNode* be = NULL;
    //大于x部分的头节点
    struct ListNode* as = NULL;
    //大于x部分的尾节点
    struct ListNode* ae = NULL;
    //cur用来遍历链表
    struct ListNode* cur = head;
    while(cur != NULL)
    {
    
    
        if(cur->val < x)
        {
    
    
        //当第一次出现小于x的节点的时候,bs和be都是这个节点
            if(bs == NULL)
            {
    
    
                bs = cur;
                be = cur;
            }
            else
            {
    
    
                be->next = cur;
                be = be->next;
            }
        }
        else
        {
    
    
        //第一次出现大于x的节点
            if(as == NULL)
            {
    
    
                as = cur;
                ae = cur;
            }
            else
            {
    
    
                ae->next = cur;
                ae = ae->next;
            }
        }
        cur = cur->next;
    }
    //判断是否有小于x的节点
    if(bs == NULL)
    {
    
    
        return as;
    }
    //连接两部分链表
    be->next = as;
    //判断是否有大于x的节点
    if(as != NULL)
    {
    
    
        ae->next = NULL;
    }

    return bs;
}

insert image description here

Java code implementation

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    
    
    public ListNode partition(ListNode head, int x) {
    
    
    //我们的Java代码与c语言略有不同,
    //我们将bs和as作为哨兵位
        if(head == null) {
    
    
            return null;
        }
        ListNode bs = new ListNode(0);
        ListNode be = bs;
        ListNode as = new ListNode(0);
        ListNode ae = as;
        ListNode cur = head;
        while(cur != null) {
    
    
            if(cur.val < x) {
    
    
                be.next = cur;
                be = be.next;
            }else {
    
    
                ae.next = cur;
                ae = ae.next;
            }
            cur = cur.next;
        }
        if(bs.next == null) {
    
    
            return as.next;
        }
        be.next = as.next;
        if(as.next != null) {
    
    
            ae.next = null;
        }

        return bs.next;
    }
}

insert image description here

intersecting list

Intersecting linked list of leetcode (difficulty: easy)

Topic requirements

Given the head nodes headA and headB of two singly linked lists, please find and return the starting node where the two singly linked lists intersect. Returns null if there is no intersecting node between the two linked lists.

The diagram shows that the two linked lists intersect at node c1:
insert image description here
the title data ensures that there is no cycle in the entire chain structure.

Note that the linked list must maintain its original structure after the function returns the result.

use case input

Example 1:
insert image description here

Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3

Output: Intersected at '8'

Explanation: The value of the intersection node is 8 (note that it cannot be 0 if the two linked lists intersect).
Counting from the respective headers, linked list A is [4,1,8,4,5] and linked list B is [5,6,1,8,4,5].
In A, there are 2 nodes before the intersection node; in B, there are 3 nodes before the intersection node.
— Note that the value of the intersecting node is not 1, because the nodes with a value of 1 in linked list A and linked list B (the second node in A and the third node in B) are different nodes. In other words, they point to two different locations in memory, and the node with value 8 in List A and List B (the third node in A, the fourth node in B) points to the same location in memory.

Example 2:
insert image description here

Input: intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1

Output: Intersected at '2'

Explanation: The value of the intersection node is 2 (note that it cannot be 0 if the two linked lists intersect).
Counting from the respective headers, linked list A is [1,9,1,2,4], and linked list B is [3,2,4].
In A, there are 3 nodes before the intersection node; in B, there is 1 node before the intersection node.

Example 3:
insert image description here

Input: intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2

Output: null

Explanation: Counting from the respective headers, linked list A is [2,6,4], and linked list B is [1,5].
Since the two linked lists are disjoint, intersectVal must be 0, while skipA and skipB can be any value.
The two linked lists are disjoint, so null is returned.

The interface provided by the topic

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    
    

}

hint

hint:

The number of nodes in listA is m
The number of nodes in listB is n
1 <= m, n <= 3 * 104
1 <= Node.val <= 105
0 <= skipA <= m
0 <= skipB <= n
If listA and listB No intersection, intersectVal is 0
If listA and listB have intersection, intersectVal == listA[skipA] == listB[skipB]

Question ideas

When the two linked lists start from the place where the number of remaining nodes is the same, they will meet at the intersection node. But because the lengths of the two linked lists are not necessarily the same, we need to find the difference len between the lengths of the two linked lists, and then let the long linked list take len steps first, and then walk together, when their addresses are the same It means that the intersection node has been reached, and we return this node.

C language implementation code

//我们将计算链表长度这个功能单独提出来,写成一个函数
int listLength(struct ListNode* head)
{
    
    
    struct ListNode* cur = head;
    int count = 0;
    while (cur != NULL)
    {
    
    
        count++;
        cur = cur->next;
    }
    return count;
}

struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB) {
    
    
//当其中一个链表为空就说明没有相交节点,我们直接返回
    if (headA == NULL || headB == NULL)
    {
    
    
        return NULL;
    }
    //我们将ll作为长度较长的链表的指针
    struct ListNode* ll = headA;
    //sl作为长度较短的链表的指针
    struct ListNode* sl = headB;
    int lenA = listLength(headA);
    int lenB = listLength(headB);
    int len = lenA - lenB;
    //如果len<0,我们就交换ll跟sl的指向
    if (len < 0)
    {
    
    
        ll = headB;
        sl = headA;
        len = -len;
    }
    for (int i = 0; i < len; i++)
    {
    
    
        ll = ll->next;
    }
    while (ll && sl)
    {
    
    
        if (ll == sl)
        {
    
    
            return ll;
        }
        ll = ll->next;
        sl = sl->next;
    }
    return NULL;
}

insert image description here

Java code implementation

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */

 //链表长的就走差值步
 //pl永远指向较长的链表
 //p2永远指向较短的链表
public class Solution {
    
    
    public int getLength(ListNode head) {
    
    
        int count = 0;
        ListNode cur = head;
        while(head != null) {
    
    
            head = head.next;
            count++;
        }
        return count;
    }
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    
    
        if(headA == null || headB == null) {
    
    
            return null;
        }
        ListNode pl = headA;
        ListNode ps = headB;
        int len1 = getLength(pl);
        int len2 = getLength(ps);
        int len = len1-len2;
        if(len < 0) {
    
    
            pl = headB;
            ps = headA;
            len = -len;
        }
        while(len != 0) {
    
    
            pl = pl.next;
            len--;
        }
        while(pl != ps) {
    
    
            pl = pl.next;
            ps = ps.next;
        }

        return pl;
    }
}

insert image description here

Guess you like

Origin blog.csdn.net/m0_73888323/article/details/130068316