算法(链表相关)

以下是链表的一些基础题目,但是通过这些题目的组合和解决问题的方法可以解决链表的复杂问题,如k个为一组进行链表翻转就需要翻转链表的方法,整理基本题目如下方便复习。

1.合并两个有序链表,合并后还是有序链表

class Solution {

    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {

        if(l1 == null){

            return l2;

        }

        if(l2 == null){

            return l1;

        }

        ListNode cur1 = l1;

        ListNode cur2 = l2;

        ListNode headVirtual = new ListNode(-1);

        ListNode cur = null;

        //确定头节点

        if(cur1.val<cur2.val){

            headVirtual.next = cur1;

            cur = cur1;

            cur1 = cur1.next; 

        }else{

            headVirtual.next = cur2;

            cur = cur2;

            cur2 = cur2.next;

        }

        //两个链表比对谁小插入谁

        while(cur1!=null && cur2!=null){

            if(cur1.val<cur2.val){

                cur.next = cur1;

                cur1 = cur1.next;

                cur = cur.next;

            }else{

                cur.next = cur2;

                cur2 = cur2.next;

                cur = cur.next;

            }

        }

        //其中一个链表全部元素已经插入

        if(cur1 == null){

            cur.next = cur2;

        }else{

            cur.next = cur1;

        }

        return headVirtual.next;

    }

}

2.去除链表中的重复元素

class Solution {

    public ListNode deleteDuplicates(ListNode head) {

        //标记当前节点

        ListNode cur = head;

         //如果下一个节点数值和当前节点相同则指向下下一个节点,否则后移当前节点

        while(cur!=null && cur.next!=null){

            if(cur.val == cur.next.val){

                cur.next = cur.next.next;

            }else{

                cur = cur.next;

            }

        }

        return head;  

    }

}

3.链表是否有环

public class Solution {

    public boolean hasCycle(ListNode head) {

        //快慢指针法,不会套圈则不会出现环,反之有环

        ListNode fast = head;

        ListNode slow = head;

        while(fast != null && fast.next != null){

            fast = fast.next.next;

            slow = slow.next;

            if(fast == slow){

                return true;

            }

        }

        return false;

    }

}

4.对链表进行排序

class Solution {

    public ListNode insertionSortList(ListNode head) {

        if(head == null){

            return null;

        }

        ListNode temp = head;

        while(temp != null){

            ListNode cur = temp.next;

            while(cur != null){

                if(cur.val<temp.val){

                    int value = temp.val;

                    temp.val = cur.val;

                    cur.val = value;

                }

                cur = cur.next;

            }

            temp = temp.next;

        }

        return head;

    }

}

5.对链表进行反转

class Solution {

    public ListNode reverseList(ListNode head) {

        //建立虚拟头节点

        ListNode headVirtual = new ListNode(-1);

        ListNode cur = head;

        //头插法反转

        while(cur != null){

            ListNode next = cur.next;

            cur.next = headVirtual.next;

            headVirtual.next = cur;

            cur = next;

        }

        return headVirtual.next;

    }

}

6.删除链表的指定节点

class Solution {

    public ListNode deleteNode(ListNode head, int val) {

        ListNode headVirtual = new ListNode(-1);

        headVirtual.next = head;

        ListNode cur = headVirtual;

        while(cur.next!=null){

            if(cur.next.val == val){

                cur.next = cur.next.next;

            }else{

                cur = cur.next;

            }

        }

        return headVirtual.next ;

    }

}

7.找出链表倒数第k个节点

class Solution {

    public ListNode getKthFromEnd(ListNode head, int k) {

        if(head == null && head.next == null){

            return head;

        }

        ListNode fast = head;

        ListNode slow = head;

        for(int i = 0;i < k;i++){

            fast = fast.next;

        }

        while(fast!=null){

            fast = fast.next;

            slow = slow.next;

        }

        return slow;

    }

}

8.两个链表的第一个公共节点

public class Solution {

    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {

        ListNode l1 = headA;

        ListNode l2 = headB;

        while(l1 != l2 ){

            if(l1 == null){

                l1 = headB;

            }else{

                l1 = l1.next;

            }

            if(l2 == null){

                l2 = headA;

            }else{

                l2 = l2.next;

            }

        }

       return l1; 

    }

}

9.k个链表为一组翻转

class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        //如果为空,或者只有一个节点,直接返回嘛
        if (head == null || head.next == null){
                return head;
        }

//给头节点一个前驱,不用单独为头节点考虑了
        ListNode headHead = new ListNode(-1);
        headHead.next = head;
        ListNode pre = headHead;
        ListNode end = headHead;
        while (end.next != null){
            //end移动到末尾
            for (int i = 0; i <k&&end!=null ; i++) {
                end = end.next;
            }
            if (end == null){
                break;
            }
            ListNode start = pre.next;
            ListNode next = end.next;
            end.next = null;
            //翻转链表,将头连接到上一个链表的末尾
            pre.next = reverse(start);
            //末尾要连接到下一个连接的next,
            start.next = next;
            pre = start;
            end = start;
        }
        return headHead.next;
    }
    private ListNode reverse(ListNode head) {
        ListNode headVirtual = new ListNode(-1);
        ListNode cur = head;
        while(cur!=null){
            ListNode next = cur.next;
            cur.next = headVirtual.next;
            headVirtual.next = cur;
            cur = next;
        }
        return headVirtual.next;

    }
}

发布了12 篇原创文章 · 获赞 9 · 访问量 579

猜你喜欢

转载自blog.csdn.net/weixin_39475445/article/details/104517144