重生之我在代码随想录刷算法第三天 | 203. 移除链表元素、707.设计链表、 206.反转链表

参考文献链接:代码随想录

本人代码是Java版本的,如有别的版本需要请上代码随想录网站查看。

203. 移除链表元素

[力扣题目链接](https://leetcode.cn/problems/binary-search/)

解题思路

这道题目还是比较简单的,目的是为了练习链表的删除操作。题目简要意思就是把链表中对应值的节点删除。

还记得第一次做这道题的时候一看题目这么简单,不就是把上一个节点的next指向下一个节点吗,结果操作一顿之后发现还是不能通过。后来看了题解才明白。

这次做的话就很清晰了,在思考这类问题时要多想想头和尾这些特殊部位。比如这道题的头节点都没有上一个节点,你还怎么让他的上一个节点指向下一个节点呢?

所以要么特殊处理,要么加入虚拟头节点

虚拟头节点

虚拟头节点的意思就是去给当前链表加一个头节点,这样你的剩余节点都可以当作普通节点处理。

代码如下

/**
 * 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) {
            if(head == null){
                return head;
            }
        	//定义一个虚拟头节点,让其指向head真正的头节点	
            ListNode vir = new ListNode();
            vir.next = head;
        	//定义一个临时节点去进行循环操作
            ListNode tmp = vir;
            while(tmp.next != null){
                //如果临时节点的下一个节点val值等于目标值,那么就进行删除操作。
                if(tmp.next.val == val){
                    tmp.next = tmp.next.next; 
                }else{
                    //否则tmp++
                    tmp = tmp.next;
                }
                千万不要把else忘记,我做的时候以为不管怎么样都得tmp++,后来思考发现如果进行了删除操作后,那么tmp的下一个节点变化了,还得继续判断它,不能tmp++}
            return vir.next;
    }
}

707.设计链表

力扣题目链接

解题思路

这道题目是刚接触链表一个很好的练手题,因为它涵盖了链表几乎所有操作。我们直接来上代码吧!

代码

要学会怎么定义链表,平时做题都是力扣帮忙定义好了,但面试万一不会定义就糟糕了。

其实只要明白了一个方法,其余的相差无几。中心思想就是通过节点.next去移动,直到自己想操作的位置进行操作,思路简单,注意一些特殊位置的判断即可

class ListNode {
    int val;
    ListNode next;
    ListNode(){}
    ListNode(int val) {
        this.val=val;
    }
}

class MyLinkedList {
    //长度
    int size;

    //虚拟头节点
    //为了操作方便统一我们还是引入虚拟头节点
    ListNode head;
    
    public MyLinkedList() {
        //初始化,size为0,只有一个虚拟头节点
        size = 0;
        head = new ListNode();
    }
    
    public int get(int index) {
        //判断index的合法性
        if(index < 0 || index >= size){
            return -1;
        }
        //通过index移动tmp,直到想要的节点
        ListNode tmp = head.next;
        for(int i = 0;i < index;i++){
            tmp = tmp.next;
        }
        return tmp.val;
    }
    
    public void addAtHead(int val) {
        //虚拟头节点立大功,不用考虑别的,直接添加即可
        ListNode add = new ListNode(val);
        ListNode tmp = head.next;
        head.next = add;
        add.next = tmp;
        size++;
    }
    
    public void addAtTail(int val) {
        //如果size为0,直接交给头节点处理就好
        if(size == 0){
            addAtHead(val);
            return;
        }
        //其实跟get方法本质一样,移动到相应位置进行操作即可
        ListNode tmp = head.next;
        for(int i = 0;i < size - 1;i++){
            tmp = tmp.next;
        }
        tmp.next = new ListNode(val);
        size++;
    }
    
    public void addAtIndex(int index, int val) {
        if(index > size){
            return;
        }
        if(index == 0){
            addAtHead(val);
            return;
        }
        ListNode tmp = head.next;
        for(int i = 0;i < index - 1;i++){
            tmp = tmp.next;
        }
        ListNode next = tmp.next;
        tmp.next = new ListNode(val);
        tmp.next.next = next;
        size++;
    }
    
    public void deleteAtIndex(int index) {
        if(index < 0 || index >= size){
            return;
        }
        ListNode tmp = head;
        for(int i = 0;i < index;i++){
            tmp = tmp.next;
        }
        tmp.next = tmp.next.next;
        size--;
    }
}

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

206.反转链表

力扣题目链接

解题思路

对于这种反转类的题目我想到的是栈和递归法。具体如何反转很简单,难的是想法和栈的使用。

首先先介绍一下栈的概念和基本使用:

它是Package java.util下的Class Stack,它是一个先进后出的数据结构。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

构造方法:

Stack() Creates an empty Stack.

方法

Modifier and TypeMethodDescription
booleanempty()判断栈是否为空
Epeek()查看栈顶部的对象并返回
Epop()移除栈顶部的对象并返回
Epush(E item)压栈:将一个元素放入栈顶
intsearch(Object o)查找对象。

相信看完这些官方api就很好解决这道题目了

代码如下:

/**
 * 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){
            return head;
        }
        Stack<ListNode> stack = new Stack<>();
        //将每个节点依次放入栈中
        while(head != null){
            stack.push(head);
            head = head.next;
        }
        //创建新的头节点,并依次接收弹出的元素排成新的链表
        ListNode newHead = stack.pop();
        ListNode tmp = newHead; 
        while(stack.size()!=0){
            tmp.next = stack.pop();
            tmp = tmp.next;
            if(stack.size()==0){
                tmp.next = null;
            }

        }
        return newHead;
    }
}
递归法
/**
 * 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) {
        reverse(null,head);
    }
    public ListNode reverse(ListNode pre,ListNode cur){
        if(cur == null){
            return pre;
        }
        ListNode tmp = cur.next;
        cur.next = pre;
        pre = cur;
        cur = tmp;
        return reverse(pre,cur);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值