代码随想录算法训练营day3 | 链表 (1)

一、链表理论基础

        链表是一种通过指针串联在一起的线性结构,每个节点由两部分组成:数据域和指针域(指向下一个节点),最后一个节点的指针指向NULL(空指针)。                                                                                                                       --Carl

 链表性能分析:

代码随想录算法训练营day3 | 链表 (1)_第1张图片

 链表的Java定义:

public class ListNode {
    // 结点的值
    int val;

    // 下一个结点
    ListNode next;

    // 节点的构造函数(无参)
    public ListNode() {
    }

    // 节点的构造函数(有一个参数)
    public ListNode(int val) {
        this.val = val;
    }

    // 节点的构造函数(有两个参数)
    public ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
}

二、LeetCode 203 移除链表元素

题目链接:203.移除链表元素icon-default.png?t=N7T8https://leetcode.cn/problems/remove-linked-list-elements/

思路:先移除符合条件的头结点,再设置虚拟头结点对之后的元素进行移除操作。

/**
 * 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) {
        //删除头结点
        while( head != null && head.val == val ){
            head = head.next;
        }
        ListNode index = head;
        //删除非头结点
        while(index != null && index.next != null){
            if(index.next.val == val){
                index.next = index.next.next;
            }else{
                index = index.next;
            }
        }
        return head;
    }
}

 三、LeetCode 707 设计链表

题目链接:707.设计链表icon-default.png?t=N7T8https://leetcode.cn/problems/design-linked-list/

思路:先考虑是否使用头结点,后创建链表节点类,再根据功能要求逐个实现。

//节点类
public class ListNode{
    int val;
    ListNode next;
    public ListNode(){
    }
    public ListNode(int val){
        this.val = val;
    }
}
class MyLinkedList {
    ListNode head;
    int length = -1;
    //无头结点链表
    public MyLinkedList() {
        head = null;
        length = 0;
    }
    
    public int get(int index) {
        //下标溢出
        if(index >= length){
            return -1;
        }
        ListNode temp = head;
        while(index > 0){
            index--;
            temp = temp.next;
        }
        return temp.val;
    }
    
    public void addAtHead(int val) {
        ListNode newNode = new ListNode(val);
        newNode.next = head;
        head = newNode;
        length++;
    }
    
    public void addAtTail(int val) {
        if(head == null){
            addAtHead(val);
        }else{
            ListNode temp = head;
            while(temp != null && temp.next != null){
                temp = temp.next;
            }
            ListNode newNode = new ListNode(val);
            temp.next = newNode;
            newNode.next = null;
            length++;
        }
        

    }
    
    public void addAtIndex(int index, int val) {
        if(index > length){
            return;
        }
        if(index == 0){
            addAtHead(val);
            return;
        }
        if(index == length){
            addAtTail(val);
            return;
        }
        ListNode newNode = new ListNode(val);
        ListNode temp = head;
        while(index > 1){
            temp = temp.next;
            index--;
        }
        newNode.next = temp.next;
        temp.next = newNode;
        length++;
    }
    
    public void deleteAtIndex(int index) {
        if(index < 0 || index >= length){
            return;
        }
        if(index == 0){
            head = head.next;
            length--;
            return;
        }
        ListNode temp = head;
        while(index > 1){
            temp = temp.next;
            index--;
        }
        temp.next = temp.next.next;
        length--;
    }
}

 刚写完出了很多小bug,没有一遍过,说明还是不够熟练,周末加练~

四、LeetCode 206 反转链表

题目链接:206.反转链表icon-default.png?t=N7T8https://leetcode.cn/problems/reverse-linked-list/

思路:翻转链表需要记录上一个节点的信息,考虑使用双指针,并设置temp指针暂存信息。

详见代码注释~

/**
 * 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) {
        //处理特殊情况
        if(head == null || head.next == null){
            return head;
        }
        ListNode now = head.next; //now存储当前节点
        ListNode cur = head;      //cur存储上一个节点
        cur.next = null;          //原头结点变尾节点
        while(now != null){
            ListNode temp = now.next;  //temp存储链表翻转前当前节点的下一个节点
            now.next = cur;            //当前节点的next指向上一个节点
            cur = now;                 //cur后移,now变cur,即本次循环的now为下次循环的cur
            now = temp;                //now后移
        }
        return cur;
    }
}

 五、今日小结

        题目难度逐渐上升,今天耗时较长;时间利用率还是不高,明天争取进一步提升效率~

你可能感兴趣的:(代码随想录算法训练营,链表,数据结构)