Linked list of Niuke online programming

Table of contents

Topic one:

Table of contents

Table of contents

Topic 1: Reversal of the specified interval of the linked list

topic description

Idea analysis

code display

Topic 2: The nodes in the linked list are flipped every k groups

topic description

problem solving ideas

code display

Topic 3 Merge two sorted linked lists

topic description

problem solving ideas

code display

Topic 4: Merge K sorted linked lists

topic description

problem solving ideas

code display

Topic 5: Judging whether there is a ring in the table

topic description

problem solving ideas

code display

Topic 6: The entry node of the ring in the linked list

topic description

problem solving ideas

code display

Topic 7: The last K nodes from the bottom of the linked list

topic description

problem solving ideas

code display

Topic 8 Delete the last N node of the linked list

topic description

problem solving ideas

code display

Topic 9 The first common node of two linked lists

topic description

problem solving ideas

code display

Topic 10 Linked List Addition (2)

topic description

problem solving ideas

code display

Topic 11 Sorting of Singly Linked Lists

topic description

problem solving ideas

code display

Topic 12: Deleting Duplicate Elements in an Ordered Linked List Ⅰ

topic description

problem solving ideas

code display

Topic 13: Delete duplicate elements in the linked list Ⅱ

topic description

problem solving ideas

code display


Topic 1: Reversal of the specified interval of the linked list

topic description

Reversing the interval between the m position and the n position of a linked list whose number of nodes is size requires time complexity O(n)O(n) and space complexity O(1)O(1).
For example:
the given linked list is 1\to 2 \to 3 \to 4 \to 5 \to NULL1→2→3→4→5→NULL, m=2,n=4m=2,n=4, return
1 \to 4\to 3\to 2\to 5\to NULL1→4→3→2→5→NULL.

Data range: Linked list length 0 < size \le 10000<size≤1000, 0 < m \le n \le size0<m≤n≤size, the value of each node in the linked list satisfies |val| \le 1000∣val∣≤ 1000

Requirements: time complexity O(n)O(n), space complexity O(n)O(n)

Advanced: time complexity O(n)O(n), space complexity O(1)O(1)

Idea analysis

Just do a simple inversion of the nodes

code display

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     *
     * @param head ListNode类
     * @param m int整型
     * @param n int整型
     * @return ListNode类
     */
    public ListNode reverseBetween (ListNode head, int m, int n) {
        // write code here
        // write code here
        ListNode res = new ListNode(-1);
        res.next = head;
        ListNode pre= res;
        ListNode cur = head;

        for (int i = 1; i < m; i++) {
            pre = cur;
            cur = cur.next;
        }

        for (int i = m; i > n; i--) {
            ListNode temp = cur.next;
            cur.next = temp.next;
            temp.next = pre.next;
            pre.next = temp;
        }
        return res.next;
    }
}

Topic 2: The nodes in the linked list are flipped every k groups

topic description

Flip the nodes in the given linked list every k groups, and return the flipped linked list
If the number of nodes in the linked list is not a multiple of k, keep the last remaining node as it is
You cannot change the value in the node, only change the node itself.

Data range: \ 0 \le n \le 2000 0≤n≤2000, 1 \le k \le 20001≤k≤2000, each element in the linked list satisfies 0 \le val \le 10000≤val≤1000 requires complex
space Degree O(1)O(1), time complexity O(n)O(n)

For example:

The given linked list is 1\to2\to3\to4\to51→2→3→4→5

For k = 2k=2 , you should return 2\to 1\to 4\to 3\to 52→1→4→3→5

For k = 3k=3 , you should return 3\to2 \to1 \to 4\to 53→2→1→4→5

problem solving ideas

Now let's think about it, if you get a linked list, what should you do if you want to group and flip like the above? First of all, it must be segmented. At least we have to divide into groups first before we can flip within the group, then flip within the group, and finally connect the reversed groups.

But there is a problem when connecting: first of all, if it can be flipped, the first element of the linked list must be the first group. This element is also to be returned, and the original linked list first connects the next set of flipped heads, that is, the tail before flipping. If a new linked list is not created, it will seem very difficult. But if we flip from the last group and get the head of the linked list of the last group, can it be directly connected to the tail of the penultimate group after flipping (that is, the head before flipping), so that from back to front is It's not as easy as it looks.

How about from the back to the front? We can use top-down and bottom-up recursion or stack at this time. Next, let's talk about why recursion can be used? If there are nnn groups in this linked list that can be reversed, we first reverse the first group, then should we connect the results of the remaining n−1n-1n−1 groups after the first group? , then the remaining n−1n-1n−1 groups are a subproblem. Let's look at the recursive three-part template:

  • Termination condition:  When the last packet is reached, that is, less than k times of traversal to the end of the linked list (0 counts), the remaining part will be returned directly.
  • Return value:  What each level needs to return is the header of the flipped packet, and the linked list of all flipped packets after it is connected.
  • Task at this level:  For each sub-problem, first traverse k times to find where the end of the group is, and then traverse from the beginning to the end of this group, flipping in turn, the end can be used as the beginning of the next group, and the element previously pointing to the beginning Has run to the end of this group, you can use it to connect the sub-problems behind it, that is, the head of the group behind.

specific methods:

  • Step 1: Traverse the linked list k times from the head node of the function each time, and separate a group. If there are less than k nodes in the follow-up, return directly to the head without inversion.
  • Step 2: Starting from the head node that enters the function, reverse the next set of linked lists in turn. The reverse process is the same as BM1. Reverse the linked list .
  • Step 3: After this group is reversed, the original head becomes the tail, followed by the reversed result of the next group, and the next group continues with the above recursion.

code display

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     *
     * @param head ListNode类
     * @param k int整型
     * @return ListNode类
     */
    public ListNode reverseKGroup (ListNode head, int k) {
        /*
        // write code here
        // 根据长度来判断可以进行几轮
        int length=numLength(head);
        int num=length/k;
        if(num<1)
            return null;
        ListNode prev=new ListNode(-1);
        prev.next=head;
        int i=0;
        ListNode res=prev;
        ListNode cur=prev.next;
        while(i<num){

            for(int j=1;j<k;j++){
                ListNode temp=cur;
                res.next=temp.next;
                temp.next=prev.next;
                prev.next=temp;
            }
            prev=cur.next;
            cur.next=prev.next;
        }
        return head;

        }
        //获得链表的长度
        public static int numLength(ListNode head){
        int length=0;
        while(head!=null){
            length++;
            head=head.next;
        }
        return length;
        }*/
        
                //找到每次翻转的尾部
                ListNode tail = head;
                //遍历k次到尾部
                for (int i = 0; i < k; i++) {
                    //如果不足k到了链表尾,直接返回,不翻转
                    if (tail == null)
                        return head;
                    tail = tail.next;
                }
                //翻转时需要的前序和当前节点
                ListNode pre = null;
                ListNode cur = head;
                //在到达当前段尾节点前
                while (cur != tail) {
                    //翻转
                    ListNode temp = cur.next;
                    cur.next = pre;
                    pre = cur;
                    cur = temp;
                }
                //当前尾指向下一段要翻转的链表
                head.next = reverseKGroup(tail, k);
                return pre;
            }
        }

    

Topic 3 Merge two sorted linked lists

topic description

Input two increasing linked lists, the length of a single linked list is n, merge the two linked lists and make the nodes in the new linked list still be sorted incrementally.

Data range: 0 ≤ n ≤ 1000, -1000 ≤ node value ≤ 1000
Requirements: space complexity O(1), time complexity O(n)

problem solving ideas

First of all, when we analyzed the topic, what we first thought of was to use one linked list to load the results of two linked lists, but what will we find if we look carefully at the topic? The space complexity is O(1), so adding a new linked list is not allowed, so what should we do?

We can use a linked list as a benchmark to compare the values ​​of the two linked lists, and whoever has the smaller first element will be inserted into the corresponding linked list! Then proceed one by one in a recursive manner!

code display

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode Merge(ListNode list1, ListNode list2) {
        //那么基本思路就是比较两个list的每一个元素,如果第一个list的元素小于第二个,那么久第一个往后走,然后第二个元素和第二个list的第一个比较,以此类推,直到最后排好序
        //因为空间复杂度为O(1),所以不允许添加新的ListNode
        if (list1 == null || list2 == null) {
            return list1 != null ? list1 : list2;
        }
        // 两个链表元素依次对比
        if (list1.val <= list2.val) {
            // 递归计算 list1.next, list2
            list1.next = Merge(list1.next, list2);
            return list1;
        } else {
            // 递归计算 list1, list2.next
            list2.next = Merge(list1, list2.next);
            return list2;
        }
    }
}

Topic 4: Merge K sorted linked lists

topic description

Merges k ascending lists and returns the result as an ascending list at its head.

Data range: total number of nodes 0 n≤5000, val of each node satisfies |val| <= 1000

Requirements: time complexity O(nlogn)

problem solving ideas

We can use the merge sorting method to solve the problem. When we solve the merge of two linked lists, our idea is to compare the characters in the two linked lists, and whoever has the smaller next value will put down a data. For multiple linked lists, you can Using the same method, first divide our linked list to the smallest, and then use the two-way merge method to go up layer by layer until the end; therefore, it can be solved by using recursion

code display

import java.util.ArrayList;
public class Solution {
    //两个链表合并函数
    public ListNode Merge(ListNode list1, ListNode list2) { 
        //一个已经为空了,直接返回另一个
        if(list1 == null) 
            return list2;
        if(list2 == null)
            return list1;
        //加一个表头
        ListNode head = new ListNode(0); 
        ListNode cur = head;
        //两个链表都要不为空
        while(list1 != null && list2 != null){ 
            //取较小值的节点
            if(list1.val <= list2.val){ 
                cur.next = list1;
                //只移动取值的指针
                list1 = list1.next; 
            }else{
                cur.next = list2;
                //只移动取值的指针
                list2 = list2.next; 
            }
            //指针后移
            cur = cur.next; 
        }
        //哪个链表还有剩,直接连在后面
        if(list1 != null) 
            cur.next = list1;
        else
            cur.next = list2;
        //返回值去掉表头
        return head.next; 
    }
    
    //划分合并区间函数
    ListNode divideMerge(ArrayList<ListNode> lists, int left, int right){ 
        if(left > right) 
            return null;
        //中间一个的情况
        else if(left == right) 
            return lists.get(left);
        //从中间分成两段,再将合并好的两段合并
        int mid = (left + right) / 2; 
        return Merge(divideMerge(lists, left, mid), divideMerge(lists, mid + 1, right));
    }
    
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
        //k个链表归并排序
        return divideMerge(lists, 0, lists.size() - 1);
    }
}

Topic 5: Judging whether there is a ring in the table

topic description

Determine whether there is a cycle in the given linked list. Returns true if there is a ring, false otherwise.

Data range: the length of the linked list is 0≤n≤10000, the value of any node in the linked list satisfies |val|<=100000

Requirements: space complexity O(1), time complexity O(n)

The input is divided into two parts, the first part is a linked list, the second part represents whether there is a ring, and then the composed head node is passed into the function. -1 means no loop, other numbers mean loop, these parameter explanations are just for the convenience of readers to self-test and debug. What is actually read in during programming is the head node of the linked list.

problem solving ideas

We use the double pointer method to solve this problem

We set two pointers, the fast pointer and the slow pointer

The fast pointer takes two steps at a time, and the slow pointer takes one step at a time; if the fast pointer finally catches up with the slow pointer, it proves that there is a loop, and if it does not catch up, it proves that there is no loop!

code display

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        //我们可以给每个节点添加一个访问状态,如果我们在找寻下一个节点的时候找寻到已经被访问了,那么就不正确
        //但是把,使用这张方式会有空间复杂度
        /*我们还可以使用双指针的方式进行,我们设置一个快指针,一个慢指针,快指针一次走两步,慢指针一次走一步
          如果最后快指针追上了慢指针,就证明存在环,否则就证明不存在
        */
        //首先判断输入进来的链表有没有值,没有就可以直接返回false,因为没有值肯定没有环
        if(head==null) return false;

        //设置快指针
        ListNode fast=head;
        //设置慢指针
        ListNode slow=head;
        while(fast!=null && fast.next!=null){
            fast=fast.next.next;  //一次走两步
            slow=slow.next;  //一次走一步
            if(fast==slow) return true;  //如果相遇了,就返回true,证明有环
        }
        return false;
    }
}

Topic 6: The entry node of the ring in the linked list

topic description

Given a linked list of length n, if it contains a ring, please find the entry node of the ring in the linked list, otherwise, return null.

Data range: n≤10000, 1<=node value<=10000

Requirements: space complexity O(1), time complexity O(n)

problem solving ideas

Then we assume that it is already a linked list with a ring, so how to find the entry of the ring in this linked list? Before the slow pointer enters the linked list ring, the fast pointer has already entered the ring and looped inside, so that after the slow pointer enters the ring, the fast pointer catches up with the slow pointer. Let’s assume that the fast pointer walks nnn circles in the ring, and the slow pointer After walking mmm circles in the ring, they meet, and the distance before entering the ring is xxx, the distance from the ring entrance to the meeting point is yyy, and the distance from the meeting point to the ring entrance is zzz. The fast pointer moves x+n(y+z)+y steps in total, and the slow pointer moves x+m(y+z)+y in total. At this time, the multiple of the fast pointer is twice that of the slow pointer, then x+ n(y+z)+y=2(x+m(y+z)+y), at this time x+y=(n−2m)(y+z), because the size of the ring is y+z, indicating The distance from the head of the linked list through the ring entrance to the meeting place is equal to the size of an integer multiple of the ring: then we traverse from the beginning to the meeting position, and start traversing in the ring from the meeting position, using the same number of steps, and both parties will eventually pass From the entrance to the y node at the meeting position, it means that these y nodes are overlapped and traversed, then they meet from the entrance position, so we will find it?

code display

public class Solution {
    //判断有没有环,返回相遇的地方
    public ListNode hasCycle(ListNode head) {
        //先判断链表为空的情况
        if (head == null)
            return null;
        //快慢双指针
        ListNode fast = head;
        ListNode slow = head;
        //如果没环快指针会先到链表尾
        while (fast != null && fast.next != null) {
            //快指针移动两步
            fast = fast.next.next;
            //慢指针移动一步
            slow = slow.next;
            //相遇则有环,返回相遇的位置
            if (fast == slow)
                return slow;
        }
        //到末尾说明没有环,返回null
        return null;
    }

    public ListNode EntryNodeOfLoop(ListNode pHead) {
        ListNode slow = hasCycle(pHead);
        //没有环
        if (slow == null)
            return null;
        //快指针回到表头
        ListNode fast = pHead;
        //再次相遇即是环入口
        while (fast != slow) {
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}

Topic 7: The last K nodes from the bottom of the linked list

topic description

problem solving ideas

We can use double pointers to

The fast pointer is faster than the slow pointer by K steps

First, if the fast pointer cannot meet the requirement of K steps faster than the slow pointer, it will exit directly, because there are no K nodes

Then if the requirements can be met, we make the fast pointer K steps faster than the slow pointer, and then when the fast pointer points to null, the slow pointer just starts to point to the starting position of the penultimate K node, and then we can return! !

code display

import java.util.*;
public class Solution {
    public ListNode FindKthToTail (ListNode pHead, int k) {
        int n = 0;
        ListNode fast = pHead;
        ListNode slow = pHead;
        //快指针先行k步
        for (int i = 0; i < k; i++) {
            if (fast != null)
                fast = fast.next;
            //达不到k步说明链表过短,没有倒数k
            else
                return slow = null;
        }
        //快慢指针同步,快指针先到底,慢指针指向倒数第k个
        while (fast != null) {
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}

Topic 8 Delete the last N node of the linked list

topic description

Given a linked list, delete the last nth node of the linked list and return the head pointer of the linked list
. For example,

The given linked list is: 1→2→3→4→5, n=2.
After deleting the last nth node of the linked list, the linked list becomes 1→2→3→5.

problem solving ideas

We still use the double pointer method. The reason why my thinking was wrong at the beginning was that I was too limited. In fact, I can add a header to the linked list, and then use three pointers to operate, the fast pointer and the slow pointer and one pointing to the slow pointer. The pointer of the previous node of the pointer, so that when the slow pointer reaches the nth node, the pre pointer just reaches the previous node of the slow pointer. At this time, just use pre.next=slow pointer.next to solve the problem! The node is deleted! !

code display

import java.util.*;
public class Solution {
    public ListNode removeNthFromEnd (ListNode head, int n) {
        //添加表头
        ListNode res = new ListNode(-1); 
        res.next = head;
        //当前节点
        ListNode cur = head; 
        //前序节点
        ListNode pre = res; 
        ListNode fast = head;
        //快指针先行n步
        while(n != 0){ 
            fast = fast.next;
            n--;
        }
        //快慢指针同步,快指针到达末尾,慢指针就到了倒数第n个位置
        while(fast != null){
            fast = fast.next;
            pre = cur;
            cur = cur.next;
        }
        //删除该位置的节点
        pre.next = cur.next; 
        //返回去掉头
        return res.next; 
    }
}

Topic 9 The first common node of two linked lists

topic description

Input two acyclic one-way linked lists, find their first common node, and return empty if there is no common node. (Note that because the incoming data is a linked list, the error test data prompt is displayed in other ways to ensure that the incoming data is correct)

problem solving ideas

We can still use the double pointer method to solve this problem

We make the two pointers point to the heads of different linked lists, and then traverse backwards one by one. We need to find the intersection point of the two linked lists. If we don’t find it at the end, the pointer on this linked list will point to another linked list. Head, and then continue to start looking, only two rounds will surely find the intersection point! !

code display

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        /* 什么是首尾相接法?
        我们指定两个指针,一个指针从head1开始,一个从head2开始,然后往后面找
        因为两个长度肯定不相等,所以一定会有一个先到达末尾,到达末尾之后我们就使得这个指针指向另外一个链表的头
        最后两个指针相遇的时候就可以得到我们最终想要的结果了
        */
        ListNode p1=pHead1;
        ListNode p2=pHead2;
        while(p1!=p2){
            p1=p1==null?pHead2:p1.next;
            p2=p2==null?pHead1:p2.next;
        }
        return p1;
    }
}

Topic 10 Linked List Addition (2)

topic description

problem solving ideas

We use two stacks, store the data in the two stacks respectively, then take the first data from the stack in turn, and define a carry flag, if the result of adding the two stacks divided by 10 is greater than 0, then Indicates that one bit needs to be entered, and then the remainder is taken, and the result of the remainder of the two values ​​is placed in the current bit! Finally we can get our result!

code display

import java.util.*;
/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     *
     * @param head1 ListNode类
     * @param head2 ListNode类
     * @return ListNode类
     */
    public ListNode addInList (ListNode head1, ListNode head2) {
        // write code here

        LinkedList<Integer> list1 = new LinkedList<>(); //list1栈
        LinkedList<Integer> list2 = new LinkedList<>(); //list2栈
        putData(list1, head1); //入栈
        putData(list2, head2);
        ListNode newNode = null;
        ListNode head = null;
        int carry = 0; //标记进位
        while (!list1.isEmpty() || ! list2.isEmpty() || carry != 0) {  //carry!=0就保证了最后一次如果还有数据的话可以保证最后一次可以获取到
            int x = (list1.isEmpty()) ? 0 : list1.pop();  //依次从栈中取出
            int y = (list2.isEmpty()) ? 0 : list2.pop();
            int sum = x + y + carry; //与进位一起相加
            carry = sum / 10; //更新进位
            //将计算值放入节点
            newNode = new ListNode(sum % 10);
            //更新下一个节点的指向
            newNode.next = head;
            head = newNode;
        }
        return head;

    }
    private static void putData(LinkedList<Integer> s1, ListNode head1) {
        if (s1 == null) s1 = new LinkedList<>();
        //遍历节点将其插入栈中
        while (head1 != null) {
            s1.push(head1.val);
            head1 = head1.next;
        }
    }
}

Topic 11 Sorting of Singly Linked Lists

topic description

Given an unordered singly linked list with n nodes, sort it in ascending order.

Data range: 0 < n≤100000

Requirements: space complexity O(n), time complexity O(nlogn)

problem solving ideas

  • Step 1: First judge that the linked list is empty or has only one element, which is directly ordered.
  • Step 2: Prepare three pointers, the fast pointer right takes two steps each time, the slow pointer mid takes one step each time, and the preorder pointer left follows the position before mid each time. Three pointers traverse the linked list. When the fast pointer reaches the end of the linked list, the slow pointer mid just walks half of the linked list, which is exactly the middle position.
  • Step 3: Disconnect the linked list from the left position, just divide it into two sub-problems and start recursion.
  • Step 4: Merge the linked lists obtained from the subproblems, refer to merging two ordered linked lists .

code display

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */
// write code here
//使用双指针进行求解
/*首先添加一个头节点,然后p1指向head,p2指向head.next 然后比较两个结点的值,如果p2<p1的话将P2节点向前移动
  以此类推,当p2到达末尾得时候,p1指针向后移动,然后p2节点重新指向p1的后一个节点,直到最后p1指向null
  当然也可以进行优化,设置一个变量记录节点上一次没有变化的位置,下一次p1直接进行跳跃就行
*/
public class Solution {
    //合并两段有序链表
    ListNode merge(ListNode pHead1, ListNode pHead2) {
        //一个已经为空了,直接返回另一个
        if (pHead1 == null)
            return pHead2;
        if (pHead2 == null)
            return pHead1;
        //加一个表头
        ListNode head = new ListNode(0);
        ListNode cur = head;
        //两个链表都要不为空
        while (pHead1 != null && pHead2 != null) {
            //取较小值的节点
            if (pHead1.val <= pHead2.val) {
                cur.next = pHead1;
                //只移动取值的指针
                pHead1 = pHead1.next;
            } else {
                cur.next = pHead2;
                //只移动取值的指针
                pHead2 = pHead2.next;
            }
            //指针后移
            cur = cur.next;
        }
        //哪个链表还有剩,直接连在后面
        if (pHead1 != null)
            cur.next = pHead1;
        else
            cur.next = pHead2;
        //返回值去掉表头
        return head.next;
    }

    public ListNode sortInList (ListNode head) {
        //链表为空或者只有一个元素,直接就是有序的
        if (head == null || head.next == null)
            return head;
        ListNode left = head;
        ListNode mid = head.next;
        ListNode right = head.next.next;
        //右边的指针到达末尾时,中间的指针指向该段链表的中间
        while (right != null && right.next != null) {
            left = left.next;
            mid = mid.next;
            right = right.next.next;
        }
        //左边指针指向左段的左右一个节点,从这里断开
        left.next = null;
        //分成两段排序,合并排好序的两段
        return merge(sortInList(head), sortInList(mid));
    }
}




Topic 12: Deleting Duplicate Elements in an Ordered Linked List Ⅰ

topic description

Delete the repeated elements in the given linked list (the elements in the linked list are ordered from small to large), so that all elements in the linked list appear only once.
For example:
the given linked list is 1→1→2, return 1→2.
The given The linked list is 1→1→2→3→3, return 1→2→3.

Data range: the length of the linked list satisfies 0≤n≤100, and the value of any node in the linked list satisfies |val|≤100

Advanced: space complexity O(1), time complexity O(n)

problem solving ideas

Or use double pointers to solve

One is in the front and the other is in the back. If p2 is not equal to p1, p1 and p2 go backward at the same time. If they are equal, move the element position to delete the element.

code display

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     *
     * @param head ListNode类
     * @return ListNode类
     */
    public ListNode deleteDuplicates (ListNode head) {
        // write code here
        //还是可以使用双指针进行求解
        /**第一个指针指在前面,第二个指针往后走,如果两个指针的值相等的话,将指针的指向进行改变
            然后删除完一个节点之后,p1指针往后移,p2指针也往后移动
            依次类推,得到最后的链表
         */
        if (head == null) return null;
        if(head.next==null) return head;
        ListNode p1 = head;
        ListNode p2 = head.next;
        while ( p2 != null) {
            if (p1.val == p2.val) {
                p1.next = p2.next;
                p2 = p2.next;
            } else {
                p1 = p1.next;
                p2 = p2.next;
            }
        }
        return head;
    }
}

Topic 13: Delete duplicate elements in the linked list Ⅱ

topic description

problem solving ideas

  • Step 1: Add a header to the linked list, and delete the first node if possible.

1

2

3

ListNode res = new ListNode(0);

//在链表前加一个表头

res.next = head;

  • Step 2: Traverse the linked list and compare two adjacent nodes each time. If two adjacent nodes are the same, open a new inner loop to traverse all the similarities in this section.
  • Step 3: In step 2, the nodes before this series of identical nodes are directly connected to the first subsequent node with different values.
  • Step 4: Remove the added header when returning.

code display

import java.util.*;
public class Solution {
    public ListNode deleteDuplicates (ListNode head) {
        //空链表
        if (head == null)
            return null;
        ListNode res = new ListNode(0);
        //在链表前加一个表头
        res.next = head;
        ListNode cur = res;
        while (cur.next != null && cur.next.next != null) {
            //遇到相邻两个节点值相同
            if (cur.next.val == cur.next.next.val) {
                int temp = cur.next.val;
                //将所有相同的都跳过
                while (cur.next != null && cur.next.val == temp)
                    cur.next = cur.next.next;
            } else
                cur = cur.next;
        }
        //返回时去掉表头
        return res.next;
    }
}

 

Guess you like

Origin blog.csdn.net/young_man2/article/details/126979655