0
点赞
收藏
分享

微信扫一扫

数据结构之链表练习题(leetCode)

gy2006_sw 2022-05-01 阅读 71

目录

1.移除链表元素(203)

public ListNode removeElements(ListNode head, int val) {
    while(head != null && head.val == val){
        head = head.next;
    }
    for (ListNode pre = head; pre != null; pre = pre.next) {
        while(pre.next != null && pre.next.val == val) {
            pre.next = pre.next.next;
        }
    }
    return head;
}
public ListNode removeElements(ListNode head, int val) {
	//链表内没有元素,终止条件
    if (head == null){
        return null;
    }
    head.next = removeElements(head.next,val);
    //删除操作
    if (head.val == val){
        return head.next;
    }
    return head;
}

2.删除排序链表中的重复元素(83)

public ListNode deleteDuplicates(ListNode head) {
    //当链表为空或者只有一个元素的时候,不可能有重复的元素
    if (head == null || head.next == null){
        return head;
    }
    ListNode pre = head;
    ListNode cur = pre.next;
    while(cur != null){
        if (pre.val != cur.val) {
            pre = pre.next;
            cur = cur.next;
        } else {
            pre.next = cur.next;
            cur = cur.next;
        }
    }
    return head;
}
public ListNode deleteDuplicates(ListNode head) {
    if (head == null || head.next == null) {
        return head;
    }
    head.next = deleteDuplicates(head.next);
    if (head.val == head.next.val) {
        return head.next;
    }
    return head;
}

在这里插入图片描述

3.删除排序链表中的重复元素 II(82)

public ListNode deleteDuplicates(ListNode head) {
    ListNode dummyHead = new ListNode();
    dummyHead.next = head;
    ListNode pre = dummyHead;
    ListNode cur = pre.next;
    while(cur != null) {
        ListNode next= cur.next;
        if (next == null){
            //链表内只有一个节点或者链表遍历完了
            break;
        } else {
            //链表内至少有两个结点
            //不相等,三指针同时向后移动,在下一次循环开始的时候,next会向后走一步
            if (cur.val != next.val) {
                pre = pre.next;
                cur = cur.next;
            } else {
            	//相等时,让next向后走到第一个不相等的元素
                while(next != null && cur.val == next.val) {
                    next = next.next;
                }
                pre.next = next;
                //cur向后走一步
                cur = next;
            }
        }
    }
    //返回头结点
    return dummyHead.next;
}

图解:
在这里插入图片描述

public ListNode deleteDuplicates(ListNode head) {
    if (head == null || head.next == null){
        return head;
    }
    if (head.val != head.next.val) {
        head.next = deleteDuplicates(head.next);
        return head;
    } else {
    	//删头结点
        ListNode nextHead = head.next;
        while (nextHead != null && head.val == nextHead.val){
            nextHead = nextHead.next;
        }
        return deleteDuplicates(nextHead);
    }
}

4.反转链表(206)

public ListNode reverseList(ListNode head) {
    ListNode dummyHead = new ListNode();
    while(head != null) {
        ListNode node = new ListNode(head.val);
        node.next = dummyHead.next;
        dummyHead.next = node;
        head = head.next;
    }
    return dummyHead.next;
}
public ListNode reverseList(ListNode head) {
    if(head == null || head.next == null) {
        return head;
    }
    ListNode pre = null;
    ListNode cur = head;
    while (cur != null) {
        ListNode next = cur.next;
        cur.next = pre;
        pre = cur;
        cur = next;
    }
    return pre;
}

在这里插入图片描述

public ListNode reverseList(ListNode head) {
    if (head == null || head.next == null){
        return head;
    }
    ListNode node = head.next;
    ListNode newHead = reverseList(head.next);
    node.next = head;
    //不能省略,会成环
    head.next = null;
    return newHead;
}

图示:在这里插入图片描述

5.链表的中间结点(876)

public ListNode middleNode(ListNode head) {
    int count = 0;
    for(ListNode x = head; x != null; x = x.next) {
        count ++;
    }
    ListNode x = head;
    for (int i = 0; i < count / 2; i++) {
        x = x.next;
    }
    return x;
}

方法二:快慢指针(双引用)

public ListNode middleNode(ListNode head) {
    ListNode fast = head;
    ListNode slow = head;
    while (fast != null && fast.next != null){
        fast = fast.next.next;
        slow = slow.next;
    }
    return slow;
}

推导:

6.链表中倒数第k个节点(剑指 Offer 22)

public ListNode getKthFromEnd(ListNode head, int k) {
    int count = 0;
    for (ListNode x = head; x != null; x = x.next) {
        count ++;
    }
    ListNode node = head;
    for (int i = 0; i < count - k; i++) {
        node = node.next;
    }
    return node;
}
public ListNode getKthFromEnd(ListNode head, int k) {
    ListNode fast = head;
    for (int i = 0; i < k ; i++) {
        fast = fast.next;
    }
    ListNode slow = head;
    while(fast != null){
        fast = fast.next;
        slow = slow.next;
    }
    return slow;
}

7.回文链表

public ListNode reverseList(ListNode head) {
    ListNode dummyHead = new ListNode();
    while(head != null) {
        ListNode node = new ListNode(head.val);
        node.next = dummyHead.next;
        dummyHead.next = node;
        head = head.next;
    }
    return dummyHead.next;
}
public boolean isPalindrome(ListNode head) {
    ListNode newLink = reverseList(head);
    while(head != null) {
        if (head.val != newLink.val) {
            return false;
        }
        head = head.next;
        newLink = newLink.next;
    }
    return true;
}
public ListNode reverse(ListNode head){
    if (head == null || head.next == null){
        return head;
    }
    ListNode node = head.next;
    ListNode newHead = reverse(head.next);
    node.next = head;
    head.next = null;
    return newHead;
}
//找中间结点
public ListNode middleNode(ListNode head){
    ListNode fast = head;
    ListNode slow = head;
    while(fast != null && fast.next != null){
        fast = fast.next.next;
        slow = slow.next;
    }
    return slow;
}
public boolean isPalindrome(ListNode head) {
    ListNode midNode = middleNode(head);
    ListNode resHead = reverse(midNode);
    while(resHead != null){
        if (head.val != resHead.val){
            return false;
        }
        resHead = resHead.next;
        head = head.next;
    }
    return true;
}

8.合并两个有序链表(21)

public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
    if (list1 == null){
        return list2;
    }
    if (list2 == null){
        return list1;
    }
    ListNode dummyHead = new ListNode();
    //新链表的尾结点
    ListNode tail = dummyHead;
    while(list1 != null && list2 != null) {
        if(list1.val <= list2.val) {
            tail.next = list1;
            tail = list1;
            list1 = list1.next;
        } else {
            tail.next = list2;
            tail = list2;
            list2 = list2.next;
        }
    }
    if (list1 == null){
        tail.next = list2;
    }
    if (list2 == null){
        tail.next = list1;
    }
    return dummyHead.next;
}
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
    if (list1 == null){
        return  list2;
    }
    if (list2 == null){
        return list1;
    }
    if (list1.val <= list2.val){
        list1.next = mergeTwoLists(list1.next,list2);
        return list1;
    }else {
        list2.next = mergeTwoLists(list2.next,list1);
        return list2;
    }

9.分割链表(02.04)

public ListNode partition(ListNode head, int x) {
    if (head == null || head.next == null){
        return head;
    }
    ListNode smallHead = new ListNode();
    ListNode smallTail = smallHead;
    ListNode bigHead = new ListNode();
    ListNode bigTail = bigHead;
    while (head != null) {
        if (head.val < x) {
            smallTail.next = head;
            smallTail = head;
        } else {
            bigTail.next = head;
            bigTail = head;
        }
        head = head.next;
    }
    bigTail.next = null;
    smallTail.next = bigHead.next;
    return smallHead.next;
}

10.相交链表(160)

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    ListNode l1 = headA;
    ListNode l2 = headB;
    while (l1 != l2) {
        l1 = l1 == null ? headB : l1.next;
        l2 = l2 == null ? headA : l2.next;
    }
    return l1;
}

图解:在这里插入图片描述

11.环形链表(141)

public boolean hasCycle(ListNode head) {
    ListNode fast = head,slow = head;
    while(fast != null && fast.next != null){
        fast = fast.next.next;
        slow = slow.next;
        //追上了
        if (fast == slow){
            return true;
        }
    }
    //直线
    return false;
}

12.反转链表 II(92)

public ListNode reverseBetween(ListNode head, int left, int right) {
    ListNode dummyHead = new ListNode();
    dummyHead.next = head;
    //pre指向待反转区间的前驱节点
    ListNode pre = dummyHead;
    //cur指向待反转区间的第一个节点
    ListNode cur = pre.next;
   	//让pre和cur走left - 1步,走到对应位置
    for (int i = 0; i < left - 1; i++) {
        pre = pre.next;
        cur = cur.next;
    }
    //只需要反转right - left次就可以
    for (int i = 0; i < right - left; i++) {
        //暂存下一个要处理的结点
        ListNode next = cur.next;
        //先删除next,在头插到pre的后面
        cur.next = next.next;
        //头插
        next.next = pre.next;
        pre.next = next;
    }
    return dummyHead.next;
}
举报

相关推荐

0 条评论