算法训练营第三天| 203.移除链表元素、707.设计链表、206.反转链表

202 阅读1分钟

LeetCode 203.移除链表元素

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode dummy = new ListNode(-1, head);

        ListNode curr = dummy;

        while(curr.next != null){
            if(curr.next.val == val){
                curr.next = curr.next.next;
            }
            else{
                curr = curr.next;
            }
        }

        return dummy.next;
    }
}

LeetCode 707.设计链表

class ListNode{
    int val;
    ListNode next;
    ListNode prev;

    public ListNode(int val){
        this.val = val;
    }
}
class MyLinkedList {
    int size;
    ListNode head;
    ListNode tail;

    public MyLinkedList() {
        size = 0;
        head = new ListNode(0);
        tail = new ListNode(0);
        head.next = tail;
        tail.prev = head;
    }
    
    public int get(int index) {
        if(index < 0 || index >= size){
            return -1;
        }
        ListNode curr;
        if(index + 1 < size - index){
            curr = head;
            for(int i = 0; i <= index; i++){ // index也是从0开始的
                curr = curr.next;
            }
        }
        else{
            curr = tail;
            for(int i = 0; i <= size - index - 1; i++){
                curr = curr.prev;
            }
        }
        return curr.val;
    }
    
    public void addAtHead(int val) {
        addAtIndex(0, val);
    }
    
    public void addAtTail(int val) {
        addAtIndex(size, val);
    }
    
    public void addAtIndex(int index, int val) { // 插入到链表中下标为 index 的节点之前
        if(index > size){ // 如果 index 比长度更大,该节点将不会插入到链表中
            return;
        }
        index = Math.max(0, index); // 如果 index 小于0,则在头部插入节点
        ListNode pred, succ; // 前一个节点、下一个节点
        if(index < size - index){
            pred = head;
            for(int i = 0; i < index; i++){
                pred = pred.next;
            }
            succ = pred.next;
        }
        else{
            succ = tail;
            for(int i = 0; i < size - index; i++){
                succ = succ.prev;
            }
            pred = succ.prev;
        }
        size++;
        ListNode toAdd = new ListNode(val);
        toAdd.prev = pred;
        toAdd.next = succ;
        pred.next = toAdd;
        succ.prev = toAdd;
    }
    
    public void deleteAtIndex(int index) { // 删除链表中下标为 index 的节点
        if(index < 0 || index >= size){
            return;
        }
        ListNode pred, succ; // 前一个节点、下一个节点
        if(index < size - index){
            pred = head;
            for(int i = 0; i < index; i++){
                pred = pred.next;
            }
            succ = pred.next.next;
        }
        else{
            succ = tail;
            for(int i = 0; i < size - index - 1; i++){
                succ = succ.prev;
            }
            pred = succ.prev.prev;
        }
        size--;
        pred.next = succ;
        succ.prev = pred;
    }
}

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList obj = new MyLinkedList();
 * int param_1 = obj.get(index);
 * obj.addAtHead(val);
 * obj.addAtTail(val);
 * obj.addAtIndex(index,val);
 * obj.deleteAtIndex(index);
 */

LeetCode 206.反转链表

双指针版

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode pre = null, cur = head;
        while(cur != null){
            ListNode nxt = cur.next;
            cur.next = pre;
            pre = cur;
            cur = nxt;
        }
        return pre;
    }
}

递归版

// 以链表1->2->3->4->5举例
class Solution {
    public ListNode reverseList(ListNode head) {
        if(head == null || head.next == null){ // 递归终止条件
            /**
            直到当前节点的下一个节点为空时返回当前节点
            由于5没有下一个节点了,所以此处返回节点5
            */
            return head;
        }

        //递归传入下一个节点,目的是为了到达最后一个节点
        ListNode newHead = reverseList(head.next);
        
        head.next.next = head;
        head.next = null;

        return newHead;
        
        /**
        第一轮出栈,head为5,head.next为空,返回5
        第二轮出栈,head为4,head.next为5,执行head.next.next=head也就是5.next=4,
                  把当前节点的子节点的子节点指向当前节点
                  此时链表为1->2->3->4<->5,由于4与5互相指向,所以此处要断开4.next=null
                  此时链表为1->2->3->4<-5
                  返回节点5
        第三轮出栈,head为3,head.next为4,执行head.next.next=head也就是4.next=3,
                  此时链表为1->2->3<->4<-5,由于3与4互相指向,所以此处要断开3.next=null
                  此时链表为1->2->3<-4<-5
                  返回节点5
        第四轮出栈,head为2,head.next为3,执行head.next.next=head也就是3.next=2,
                  此时链表为1->2<->3<-4<-5,由于2与3互相指向,所以此处要断开2.next=null
                  此时链表为1->2<-3<-4<-5
                  返回节点5
        第五轮出栈,head为1,head.next为2,执行head.next.next=head也就是2.next=1,
                  此时链表为1<->2<-3<-4<-5,由于1与2互相指向,所以此处要断开1.next=null
                  此时链表为1<-2<-3<-4<-5
                  返回节点5
        出栈完成,最终头节点5->4->3->2->1
         */
    }
}

反转链表是必记题