leetcode-探索链表

1.环形列表
/*
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:40.2 MB, 在所有 Java 提交中击败了21.14%的用户
*/
 public boolean hasCycle(ListNode head) {
    
    
         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;
         }
         return false;
    }
2.环形链表 II
/*
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:40 MB, 在所有 Java 提交中击败了36.04%的用户
*/
 public ListNode detectCycle(ListNode head) {
    
    
        if(head==null||head.next==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) break;
        }
        if (slow!=fast) return null;
        slow = head;
        while (slow!=fast){
    
    
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }

3.相交链表

在这里插入图片描述

/*
执行用时:1 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:42.3 MB, 在所有 Java 提交中击败了97.90%的用户
*/
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    
    
        if (headA==null||headB==null) return null;
        ListNode A = headA;
        ListNode B = headB;
        while (A!=B){
    
    
            A = A!=null?A.next:headB;
            B = B!=null?B.next:headA;
        }
        return A;
    }
4.删除链表的倒数第N个节点
/*
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:38.1 MB, 在所有 Java 提交中击败了27.98%的用户
*/
 public ListNode removeNthFromEnd(ListNode head, int n) {
    
    
         if (head==null||(head.next==null&&n == 1)) return null;
         ListNode fast = head;
         ListNode slow = head;
         ListNode pre = head;
    	 // 让快指针先走n步
         while (n>0){
    
    
             fast = fast.next;
             n--;
         }
    	 // 当fast=null时,说明移除的是第一个元素
         if (fast == null){
    
    
             head = head.next;
         }
    	 // 当fast=null时,slow指向被删除的值
         while (fast!=null){
    
    
             fast = fast.next;
             pre = slow;
             slow = slow.next;
         }
         pre.next = slow.next;
         return head;
    }

5.反转链表

在这里插入图片描述

/*
递归做法,图解如上图
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:39.5 MB, 在所有 Java 提交中击败了68.79%的用户
*/
public ListNode reverseList(ListNode head) {
    
    
        if(head==null||head.next==null) return head;
        ListNode last = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return last;
    }


/*
迭代做法
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:40 MB, 在所有 Java 提交中击败了9.74%的用户
*/
public ListNode reverseList(ListNode head) {
    
    
        if(head==null) return head;
        ListNode pre = null;
        ListNode temp = head;
        while(temp!=null){
    
    
            ListNode n = temp.next;
            temp.next = pre;
            pre = temp;
            temp = n;
        }
        return pre;
    }
6.反转链表 II
/*
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:37.1 MB, 在所有 Java 提交中击败了95.79%的用户
*/
class Solution {
    
    
    //保存第n+1个结点
    ListNode note = null;
    public ListNode reverseBetween(ListNode head, int m, int n) {
    
    
        if(m==1) return reverseN(head, n);
        //找到需要反转的第一个结点
        head.next = reverseBetween(head.next,m-1,n-1);
        return head;
    }
    private ListNode reverseN(ListNode head, int n){
    
    
        if (n==1) {
    
    
            note = head.next;
            return head;
        }
        ListNode last = reverseN(head.next, n-1);
        head.next.next = head;
        head.next = note;
        return last;
    }

}
7.移除链表元素
/*
执行用时:1 ms, 在所有 Java 提交中击败了99.71%的用户
内存消耗:40.6 MB, 在所有 Java 提交中击败了71.74%的用户
*/
 public ListNode removeElements(ListNode head, int val) {
    
    
        ListNode pre = null;
        ListNode temp = head;
        while(temp!=null){
    
    
            ListNode n = temp.next;
            //当temp为选定的目标值时
            if(temp.val == val){
    
    
                //当链表的第一个元素为所选定的目标值时
                if(pre==null){
    
    
                    head = n;
                    temp = n;
                }else{
    
    
                pre.next = n;
                temp = n;
                }
               
            }
            //当temp不是该目标值,继续往下走
            else{
    
    
                pre = temp;
                temp = n;
            }
        }
        return head;
    }
8.奇偶链表

9.回文链表
/*
1.找到中间位  2.从中间位开始逆转 3.比较
执行用时:1 ms, 在所有 Java 提交中击败了99.72%的用户
内存消耗:43.3 MB, 在所有 Java 提交中击败了38.26%的用户
*/
class Solution {
    
    
    public boolean isPalindrome(ListNode head) {
    
    
        if(head==null||head.next==null) return true;
        ListNode fast = head;
        ListNode slow = head;
        ListNode pre = head;
        //当链表的个数为奇数时,slow最终停在中点处
        //为偶数时,slow最终停在左边中点处
        while (fast.next!=null&&fast.next.next!=null){
    
    
            fast = fast.next.next;
            slow = slow.next;
        }
        slow.next = reverse(slow.next);
        while (slow.next!=null){
    
    
            if (head.val!=slow.next.val){
    
    
                return false;
            }
            head = head.next;
            
            slow = slow.next;
        }
        return true;
    }

    private ListNode reverse(ListNode head) {
    
    
        if (head.next==null) return head;
        ListNode last = reverse(head.next);
        head.next.next = head;
        head.next = null;
        return last;
     }

}
10.合并两个有序链表
/*
执行用时:1 ms, 在所有 Java 提交中击败了63.12%的用户
内存消耗:39.6 MB, 在所有 Java 提交中击败了24.87%的用户
*/
class Solution {
    
    
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    
    
        ListNode ll = new ListNode(0);
        ListNode l3 = ll;
        while(l1!=null&&l2!=null){
    
    
            if(l1.val<=l2.val){
    
    
                l3.next = l1;
                l1 = l1.next;
            }
            else{
    
    
                l3.next = l2;
                l2= l2.next;
            }
            l3 = l3.next;
        }
        l3.next = l1==null?l2:l1;
        return ll.next;
    }
}
11.两数相加
/*
看似简单,实则需要考虑进位问题,在将多次尝试将字符串转化成数字结果溢出之后,借鉴网上代码。
执行用时:2 ms, 在所有 Java 提交中击败了99.89%的用户
内存消耗:40 MB, 在所有 Java 提交中击败了24.93%的用户
*/
class Solution {
    
    
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    
    
        ListNode head1 = l1;
        ListNode head2 = l2;
        ListNode newHead = new ListNode(0);
        ListNode head3 = newHead;
        // 进位标志
        boolean carry = false;
        while (head1 != null || head2 != null) {
    
    
            // 获取对应位置的值然后相加
            int x = (head1 != null) ? head1.val : 0;
            int y = (head2 != null) ? head2.val : 0;
            int sum = carry ? (x + y + 1) : (x + y);
            // 处理进位
            if (sum >= 10){
    
    
                sum -= 10;
                carry = true;
            } else {
    
    
                carry = false;
            }
            // 新增节点
            head3.next = new ListNode(sum % 10);
            head3 = head3.next;
            if (head1 != null) head1 = head1.next;
            if (head2 != null) head2 = head2.next;
        }
        if (carry) {
    
    
            head3.next = new ListNode(1);
        }
        return newHead.next;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41458842/article/details/108070948