代码随想录算法训练营第三天| 203.移除链表元素 707.设计链表 206.反转链表

72 阅读2分钟

203.移除链表元素203. 移除链表元素 - 力扣(LeetCode)代码随想录 (programmercarl.com)

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点

删除链表中间一个节点的操作只需将前一个结点的下一个节点设为删除节点的下一个节点即可,但是如果要删除头节点则要设置新的头节点,那么怎样方便删除呢,我们可以在头节点之前增加一个虚拟节点,用它来遍历,并在途中判断删除的是否为头节点,若是则更新头节点,也可以增加一个虚拟头节点,再用另一个指针去遍历链表,以下为具体代码实现:

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode ptr=new ListNode();
        ptr.next=head;
        while(ptr!=null){
            if(ptr.next==null)
                return head;
            if(ptr.next.val==val){
                if(ptr.next==head){
                    head=head.next;
                }
                else{
                    ptr.next=ptr.next.next;
                    continue;
                }
            }
            ptr=ptr.next;
        }
        return head;
    }
}

707.设计链表代码随想录 (programmercarl.com)

有思路即可。

class MyLinkedList {
    int size;
    ListNode head;

    public MyLinkedList() {
        size = 0;
        head = new ListNode(0);
    }

    public int get(int index) {
        if (index < 0 || index >= size) {
            return -1;
        }
        ListNode cur = head;
        for (int i = 0; i <= index; i++) {
            cur = cur.next;
        }
        return cur.val;
    }

    public void addAtHead(int val) {
        addAtIndex(0, val);
    }

    public void addAtTail(int val) {
        addAtIndex(size, val);
    }

    public void addAtIndex(int index, int val) {
        if (index > size) {
            return;
        }
        index = Math.max(0, index);
        size++;
        ListNode pred = head;
        for (int i = 0; i < index; i++) {
            pred = pred.next;
        }
        ListNode toAdd = new ListNode(val);
        toAdd.next = pred.next;
        pred.next = toAdd;
    }

    public void deleteAtIndex(int index) {
        if (index < 0 || index >= size) {
            return;
        }
        size--;
        ListNode pred = head;
        for (int i = 0; i < index; i++) {
            pred = pred.next;
        }
        pred.next = pred.next.next;
    }
}

class ListNode {
    int val;
    ListNode next;

    public ListNode(int val) {
        this.val = val;
    }
}

206.反转链表代码随想录 (programmercarl.com)

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

第一想法是遍历链表,并且用头插法插入新链表。实现如下:

/**
 * 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 reverseList(ListNode head) {
        ListNode cur=head;
        ListNode newHead=null;
        while(cur!=null){
            ListNode node=new ListNode(cur.val,newHead);
            newHead=node;
            cur=cur.next;
        }
        return newHead;
    }
}

但是这种方法相当于重新新建了一个链表,浪费了空间,实际上在当前链表中使用双指针法进行操作即可,空间复杂度仅为O(1)。代码如下:

// 双指针
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode prev = null;
        ListNode cur = head;
        ListNode temp = null;
        while (cur != null) {
            temp = cur.next;// 保存下一个节点
            cur.next = prev;
            prev = cur;
            cur = temp;
        }
        return prev;
    }
}