代码随想录算法训练营第三天 |203.移除链表元素 707.设计链表 206.反转链表

首先链表的定义里内存空间不连续,节点通过指针指向下一地址。链表适合增删改,访问的时间复杂度较高o(n),特性与数组相反。

手写单向链表节点定义如下,每个节点包括元素和指向下个节点指针两部分。

typedef struct ListNode{
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}//构造函数便于初始化 
} ListNode;

203.移除链表元素

题目输入一个链表的头节点和一个值,要求返回删除这个值的链表节点。

由于不同节点是通过指针相连接的,所以要删除节点正常只需要把前一个节点的指针指向下一个节点就可以,但是头节点没有前一个节点,所以虚拟头节点的作用就来力。

先创建虚拟头节点dummyhead:初始化并把指针指向head节点。利用临时节点指针cur遍历,找到目标值就执行删除操作,改指针指向。

注意事项:

1.遍历链表的写法while(cur->next!=NULL){ cur=cur->next };

2.删除链表的时候不能直接改指针指向,中间删除部分需要先存到tmp里再delete,否则会造成内存泄漏;

3.cur是指向dummyhead的结构体类型的指针,起到遍历作用;

4.不能直接return head因为有可能原头节点被删除,所以要先利用dummyhead介入;

707.设计链表

挺哈人的一道题,考察各种链表基本操作:

0.链表定义

1.获取第n个节点的值(输入索引返回值

2.头部插入节点

3.尾部插入节点

4.第n个节点前插入节点

5.删第n个节点

链表定义不多说,元素和指针还有构造函数必须掌握。

初始化链表:

获取第n个值:

这里的遍历方式也是用cur指针,不过起始位置不同于上题。时间关系这里就偷别人的代码(这题好像手撕频率不高偷个懒

头部插入节点:

后面几种也是同理的,关键都是要会创建新节点、会用while遍历链表。

这题用来回顾链表基础操作是很好的,不过代码也太长而且没考察算法面试可能性应该小,标记一下以后二刷,别为此消磨了耐心。。。

206.反转链表

这题面试频率很高!需要重点掌握!

看眼题目

很好理解。解法有双指针和递归,递归我太菜了学不懂,用双指针解

说是双指针其实是三指针,cur、pre、next分别记,只有前两者的话当前节点反转后下一个节点没办法保存,所以三指针是必要的。创建三个指针pre、cur、next并注意初始化,执行循环:next指向pre,pre和cur指针向右移动,最后返回的是头节点也就是pre

我发现思路混乱的原因总是把=理解后者赋值给前者,其实链表里的next就可以直接视作指向箭头,把pre=cur视作指针的移动,代码就好理解很多,可以想象一下三行代码分别对应三个指针next、pre、cur按次序移动的画面,第二行执行对应着箭头换向。

今日总结

虚拟头节点dummyhead和临时指针cur方法必须掌握,链表经常考察。创建新节点、创建指针、while遍历链表的写法是一定要会的,反转链表重中之重

由于提供的引用中未涉及Java实现移除链表元素时main方法中的输入处理的相关内容,下面是一个示例代码展示该场景下main方法的输入处理方式。此示例假设输入是一系列整数表示链表元素,以及一个整数表示要移除元素。 ```java import java.util.Scanner; // 定义链表节点类 class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } public class RemoveLinkedListElements { public static ListNode removeElements(ListNode head, int val) { // 创建一个虚拟头节点 ListNode dummy = new ListNode(0); dummy.next = head; ListNode prev = dummy; ListNode curr = head; while (curr != null) { if (curr.val == val) { prev.next = curr.next; } else { prev = curr; } curr = curr.next; } return dummy.next; } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // 读取链表元素,假设输入以空格分隔 System.out.println("请输入链表元素,以空格分隔:"); String[] input = scanner.nextLine().split(" "); ListNode dummy = new ListNode(0); ListNode current = dummy; for (String num : input) { current.next = new ListNode(Integer.parseInt(num)); current = current.next; } ListNode head = dummy.next; // 读取要移除元素 System.out.println("请输入要移除元素:"); int valToRemove = scanner.nextInt(); // 移除元素 ListNode newHead = removeElements(head, valToRemove); // 输出移除元素后的链表 System.out.println("移除元素后的链表:"); current = newHead; while (current != null) { System.out.print(current.val + " "); current = current.next; } scanner.close(); } } ``` 在上述代码中,`main` 方法使用 `Scanner` 类从控制台读取用户输入。首先读取一系列以空格分隔的整数作为链表元素,然后读取一个整数作为要移除元素。接着调用 `removeElements` 方法移除指定元素,并输出移除元素后的链表
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值