JAVA二刷-Day3 203.移除链表元素,707.设计链表 ,206.反转链表

JAVA二刷-Day3| 203.移除链表元素,707.设计链表 ,206.反转链表

移除链表元素

LeetCode题目链接:https://leetcode.cn/problems/remove-linked-list-elements/

解题思路

  先看题目,因为要在链表中删去等于val值的元素,如果从head开始迭代会存在问题:如果head也需要被删去,那么需要对head进行特殊处理,以适应新的头结点,非常麻烦。

  因此,首先初始化一个虚拟头结点来作为当前的头结点,不用担心头结点的特殊处理。之后进行迭代,如果指向的节点的下一个节点val符合要求,则将节点的next指向原先的next->next。 同时,要注意在判定cur.next是否为空之前,需要判定cur是否为空。

  值得注意的是,当进行节点删除的操作后,不需要再将节点后移。以保证更新后的节点都可以被迭代到。否则相当于删去后跳过了一个节点。代码如下:

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode dummyHead = new ListNode(0,head);
        ListNode cur = dummyHead;
        while (cur != null && cur.next != null) {
            if (cur.next.val == val) {
                cur.next = cur.next.next;
            }else {
                cur = cur.next;
            } 
        }

        return dummyHead.next;
    }
}

设计链表

LeetCode题目链接:https://leetcode.cn/problems/design-linked-list/

解题思路

  观察可以得到,初始化时链表为空,为了给初始添加链表元素提供根据,在初始化阶段应当设置出一个虚拟头结点,以满足插入和删除元素的需要(不能直接放入node节点,来作为计算,因为会造成多了一个节点的错误)。同时,addAtIndex中存在索引参数,并且需要对索引参数进行判定,因此初始化中应当有方法对当前链表的长度进行统计。因此,还应该引入len变量来计入链表长度。

  此后,addAtHead和addAtTail可以看成addAtIndex操作的一个特例。所以仅对增删和get进行重点书写。

  注意事项:1、addAtIndex 方法中描述的“如果 index 等于链表的长度,则该节点将附加到链表的末尾” 这句话中 链表长度这里是指 size而不是size - 1,如果是size-1的话那就会和在最后一个元素前插入冲突了。2、这里的index是从0开始的。
  具体代码如下:

class MyLinkedList {

    private ListNode dummyHead;

    private int len;

    public MyLinkedList() {

        dummyHead = new ListNode(0,null);
        len = 0;
    }

    public int get(int index) {
        if (index >= len) return -1;

        ListNode curr = dummyHead.next;

        while (index > 0) {
            curr = curr.next;
            index--;
        }

        return curr.val;
    }

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

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

    public void addAtIndex(int index, int val) {
        if (index > len) return;

        ListNode add = new ListNode(val,null);
        ListNode curr = dummyHead;
        ListNode temp = curr.next;
        while (index > 0) {
            curr = curr.next;
            temp = curr.next;
            index--;
        }
        curr.next = add;
        add.next = temp;
        len++;
    }

    public void deleteAtIndex(int index) {
        if (get(index) == -1) return;

        ListNode pre = dummyHead;
        ListNode curr = pre.next;
        
        while (index > 0) {
            pre = curr;
            curr = curr.next;
            index--;
        }
        pre.next = curr.next;
        len--;

    }
}

反转链表

LeetCode题目链接:https://leetcode.cn/problems/reverse-linked-list/

解题思路

  采用双指针迭代法,逐步对两两元素进行迭代。注意双指针初始值的选择,设为NULL可以满足链表末尾元素指向NULL的要求。

具体代码如下:

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode pre = null;
        ListNode curr = head;
        ListNode temp;

        while (curr != null) {
            temp = curr.next;
            curr.next = pre;
            pre = curr;
            curr = temp;
        }

        return pre;

    }
}

  此外,也可以使用递归的方法来进行,在使用递归首先要确定终止条件,即当快指针的值为null时,说明已经到了最后一个元素。此时应该返回最后一个节点的值。其他和双指针法没有区别:

class Solution {
    public ListNode reverseNode (ListNode pre, ListNode curr) {
        if (curr == null) return pre;

        ListNode temp = curr.next;
        curr.next = pre;

        return reverseNode(curr, temp);
    }

    public ListNode reverseList(ListNode head) {

        return reverseNode(null, head);

    }
}

你可能感兴趣的:(java,链表,开发语言)