您现在的位置是:首页 >技术杂谈 >算法记录lday3 LinkedList 链表移除 + 链表构建 + 链表反转reverse网站首页技术杂谈

算法记录lday3 LinkedList 链表移除 + 链表构建 + 链表反转reverse

生产队的驴儿 2023-06-16 20:00:02
简介算法记录lday3 LinkedList 链表移除 + 链表构建 + 链表反转reverse

今日任务

● 链表理论基础
● 203.移除链表元素
● 707.设计链表
● 206.反转链表

链表理论基础

建议:了解一下链接基础,以及链表和数组的区别

文章链接:https://programmercarl.com/%E9%93%BE%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html

203.移除链表元素

建议: 本题最关键是要理解 虚拟头结点的使用技巧,这个对链表题目很重要。

题目链接/文章讲解/视频讲解::https://programmercarl.com/0203.%E7%A7%BB%E9%99%A4%E9%93%BE%E8%A1%A8%E5%85%83%E7%B4%A0.html

707.设计链表

建议: 这是一道考察 链表综合操作的题目,不算容易,可以练一练 使用虚拟头结点

题目链接/文章讲解/视频讲解:https://programmercarl.com/0707.%E8%AE%BE%E8%AE%A1%E9%93%BE%E8%A1%A8.html

206.反转链表

建议先看我的视频讲解,视频讲解中对 反转链表需要注意的点讲的很清晰了,看完之后大家的疑惑基本都解决了。

题目链接/文章讲解/视频讲解:https://programmercarl.com/0206.%E7%BF%BB%E8%BD%AC%E9%93%BE%E8%A1%A8.html

DeleteNode链表 leetcode

链接

https://leetcode.com/problems/remove-linked-list-elements/

题目表示

Given the head of a linked list and an integer val, remove all the nodes of the linked list that has Node.val == val, and return the new head.
在这里插入图片描述

思路

use one poiner cur to iterate thorough the whole linkedlist

whne the cur.val == val
remove this element

犯错点

处理头结点为目标值的情况,要用while循环处理
In the case of processing the head node as the target value,
it should be processed in a while loop.
处理完之后,判断head是否为空
After processing, determine if the head is empty
在循环删除 val 时,要使用一个pre变量表示 cur前的一个节点
When iteratively deleting val, use a pre variable to represent a node before cur

在处理 cur.val = val 时, prev.next = cur.next;
另外一种情况是, pre = cur; 更新 pre的位置

这两种情况都需要 移动 cur
cur = cur.next;

在这里插入图片描述

代码

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        while (head != null && head.val == val) {
            head = head.next;
        }

        if(head == null) {
            return null;
        }

        ListNode pre = head;
        ListNode cur = head.next;

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

            cur = cur.next;
        }

        return head;
    }
}

思路简化

通过创建 一个dummyNode 在 head前面
避免对于 head.val == val的特殊情况的处理
By creating a dummyNode in front of the head
to Avoid handling special cases of head.val == val

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;

        ListNode cur = dummy;

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

        return dummy.next;
    }
}

Design链表 leetcode 707

链接

https://leetcode.com/problems/design-linked-list/

题目描述

Design your implementation of the linked list. You can choose to use a singly or doubly linked list.
A node in a singly linked list should have two attributes: val and next. val is the value of the current node, and next is a pointer/reference to the next node.
If you want to use the doubly linked list, you will need one more attribute prev to indicate the previous node in the linked list. Assume all nodes in the linked list are 0-indexed.

Implement the MyLinkedList class:

MyLinkedList() Initializes the MyLinkedList object.
int get(int index) Get the value of the indexth node in the linked list. If the index is invalid, return -1.
void addAtHead(int val) Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list.
void addAtTail(int val) Append a node of value val as the last element of the linked list.
void addAtIndex(int index, int val) Add a node of value val before the indexth node in the linked list. If index equals the length of the linked list, the node will be appended to the end of the linked list. If index is greater than the length, the node will not be inserted.
void deleteAtIndex(int index) Delete the indexth node in the linked list, if the index is valid.

代码

class MyLinkedList {
    Node head;
    Node tail;
    int cap;

    public MyLinkedList() {
        this.head = new Node(-1);
        this.tail = new Node(-1);
        this.cap = 0;

        this.head.next = tail;
        this.tail.prev = head;

    }

    public Node getNode(int index) {

        Node cur = head.next;
        for (int i = 0; i < index; i++) {
            cur = cur.next;
        }

        return cur;
    }
    
    public int get(int index) {
        
        if(index < 0 || index >= cap) {
            return -1;
        }

        Node cur = getNode(index);

        return cur.val;

    }

    
    public void addAtHead(int val) {
        Node x = new Node(val);
        
        x.prev = this.head;
        x.next = head.next;

        head.next.prev = x;
        head.next = x;

        this.cap++;
    }
    
    public void addAtTail(int val) {
        Node x = new Node(val);

        x.prev = tail.prev;
        x.next = this.tail;

        tail.prev.next = x;
        tail.prev = x;

        this.cap++;
    }
    
    public void addAtIndex(int index, int val) {

        if (index > this.cap || index < 0) return;

        Node x = new Node(val);

        Node cur = getNode(index);

        Node p1 = cur.prev;
        Node p2 = cur;

        p1.next = x;
        p2.prev = x;

        x.prev = p1;
        x.next = p2;

        this.cap++;
    }
    
    public void deleteAtIndex(int index) {

        if (index >= this.cap || index < 0) return;

         Node cur = getNode(index);

        Node p1 = cur.prev;
        Node p2 = cur.next;

        p1.next = p2;
        p2.prev = p1;

        cur.next = cur.prev = null;

        this.cap--;
    }
}

class Node{
    int val;
    Node prev;
    Node next;

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

/**
 * 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);
 */

思路

设计一个linkedlist
Design a linkedlist
实现增删插改
Realize addition, deletion, insertion and modification

create Node class first
suggest use doubleNode
own three attribution
val
prev
next

create DoubleLinkedList
head
tail
size

don’t forget to update size,
when each time you implentent the insert, add, remove function

犯错点

对于get,insert, remove等方法
开始要进行index的检查
For get, insert, remove and other methods
need index check.

get 和 remove 检查 index是否 0 - size - 1内
Get and remove check whether the index is 0 - size - 1
insert 检查 index是否 0 - size内
Insert to check if the index is within 0- size
使用cur = head.next
for (i =0 ;i<index;i++ ) cur = cur.next;
就可以找到该节点位置

可以单独创建getNode方法使用
因为要经常使用这个
You can create the getNode method separately to use
Because we need to use this frequently

通过 getNode找到cur点之后

先处理 x 和 prev 和 cur关系

链表反转 Reverse LinkedList

思路

  1. consider the spcial case
  2. use two pointer

cur and prev to reverse the linkedlist

代码

指针

class Solution {

    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) return head;

        ListNode cur = head, prev = null;

        while (cur != null) {
            ListNode next = cur.next;
            cur.next = prev;
            prev = cur;
            cur = next;
        }

        return prev;
    }
}

递归

这里定义的 reverseList
输入为 head
输出为 反转 head开头的链表

last = reverseList(head.next)
反转 head.next 开头的链表

head.next 是 head下一个指针
head.next.next = head 让head下一个指针指向 head
head.next = null 让head指向null节点

class Solution {

    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;
    }
}

指针变得递归

class Solution {

    public ListNode reverseList(ListNode head) {
        return reverse(null, head);
    }

    ListNode reverse(ListNode prev, ListNode cur) {
        if (cur == null) return prev;

        ListNode next = cur.next;
        cur.next = prev;
        
        return reverse(cur, next);
    }
}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。