代码随想录训练营day03记录: 链表移除, 设计链表, 反转链表

链表元素移除:
一段时间没做都有点忘记了, 重点思路就是设置虚拟头节点, 然后再建立一个curr临时节点搜索数据, curr直接等于dummy, 所以就可以利用curr.next来做判断

细节思路:
1. 链表固定的开头: 判断head是否为空

2.需要一个dummyHead,需要一个临时节点cur

3.记住节点的定义就是用 ListNode了

4. 进入while循环,保证cur.next不等于空

5.判断cur.next.val = val, 如果是就改变指针删除,不是就继续找下一个,最后返回dummy.next

因为dummy是一个虚拟头节点,是没有含义的

(while记得是符合条件才执行循环)

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        if(head == null){
            return head;
        }

        ListNode dummy = new ListNode(666);  //虚拟头节点的数无意义
        dummy.next = head;
        ListNode cur = dummy; //表示上一个节点,用来找数,画图就可以理解了
        while(cur.next != null){
            if(cur.next.val == val){
                cur.next = cur.next.next;
            } else {
                cur = cur.next;
            }
        }
        return dummy.next;
    }
}

==================================================================================================================================================

设计链表:
这里基础比较薄弱,所以需要对定义进行一些复习,链表需要的东西:
1. Main方法

2. 定义节点:

a. class ListNode-----int val, ListNode next; 等等

b. 构造器:空参和有参

3. 定义链表:

a. class LinkedList---int size, ListNode dummyHead

b.然后开始初始化链表.size = 0, ListNode dummyHead = new dummyHead(0);

开始解题,总体思路: 需要定义一个虚拟头节点, 然后定义一个cur去遍历寻找所需要的值,不管是删除,添加还是查找,只需要改变遍历的参数,让cur停在所需要的地方就可以解决问题.
细节:
1. 一定要判断index是否在链表范围里, 所以不能小于0, 不能大于等于size (因为size总比index小一位数)

2. 判断如果成功, 永远记得写return直接结束啊!!  

3.创建新的节点时, 记得ListNode new = .. 保证基础语法正确; 还有cur.val的使用方法

4.永远记住先定义虚拟节点, 然后直接用遍历cur = cur.next去移动cur

5. 对于addIndex方法, index小于0,就直接加头节点, 大于size就直接return;

7.分清楚cur的位置, 当查找时,需要cur直接停在那个数, 所以遍历应该写i <= index; 但是添加和删除的时候, 要把cur停在n前面, 所以i < index;

8.添加细节:停在n前面, 然后新的节点指向n(new.next = cur.next), cur指向新的节点

  删除细节: 跨过n改变指针, 停在n前面, cur指向下下个(cur.next = cur.next.next)--如果index是头节点,直接head = head.next

class MyLinkedList {
    int size;
    ListNode dummyHead;

    //初始化链表
    public MyLinkedList() {
        size = 0;
        dummyHead = new ListNode(0);

    }

    //get方法, 寻找,然后用val返回    
    public int get(int index) {
        if(index < 0 || index >= size){
            return -1;
        }
        //定义一个cur去寻找数字,用遍历就行
        ListNode cur  = dummyHead;
        for(int i = 0; i<= index; i++){ //index和size的定义
            cur = cur.next;
        }
        return cur.val;
    }
    //添加头部方法
    public void addAtHead(int val) {
        addAtIndex(0, val);
        
    }
    //添加尾部方法
    public void addAtTail(int val) {
        addAtIndex(size, val);

    }
    //在第n个前面添加方法
    public void addAtIndex(int index, int val) {
        if(index > size){
            return;
        }
        if(index < 0){
            index = 0;
        }
        size++;
        ListNode add = new ListNode(val);
        ListNode pre = dummyHead;
        for(int i = 0; i < index; i++){
            pre = pre.next;  //指针不断前移,停到n前面的位置
        }
        add.next = pre.next;
        pre.next = add;
    }
    //删除方法
    public void deleteAtIndex(int index) {
        if(index < 0 || index >= size){
            return;  
        }
        size--;
        if(index == 0){
            dummyHead = dummyHead.next;
            return;
        }
        ListNode cur = dummyHead;
        for(int i = 0; i < index; i++){
            cur=cur.next;
        }
        cur.next = cur.next.next;

    }
}

==================================================================================================================================================

反转链表:

这道题分为双指针和递归解法, 双指针解法还是比较容易的.

双指针思路: 需要先定义两个节点,pre, cur,定义完之后直接进入while循环, 条件是(cur != null), 当cur等于null的时候就不要反转了, 然后很简单,  定义next节点, next是用来存储下一个; 开始反转链表, 反转完之后, cur和pre全部集体往后移动.

(记住节点的话用ListNode定义, 不是int了)

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

递归写法:
其实就是双指针写法的转换, 首先定义一个reverse方法,来进行递归, 里面传入的参数和双指针一样 reverse(null, head), 因为pre = null; cur = head;  base case就是if(cur == null) {return pre}, 对于里面1.还是要写next = cur.next保存数值, 然后 cur.next = pre, 然后再次调用reverse(cur, next) (把pre付给cur, 把cur付给next)

(记住方法里的参数应该填什么就行了, 首先时初始化的值, 然后方法内就是向右移动的值)

class Solution {
    public ListNode reverseList(ListNode head) {
        return reverse(null, head);   //这里就直接给初始值
    }

       public ListNode reverse(ListNode pre, ListNode cur){
           if(cur == null){
               return pre;
           }
           ListNode next = cur.next;
           cur.next = pre;
           return reverse(cur, next); //全体向前移动
       }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值