赞
踩
前沿:撰写博客的目的是为了再刷时回顾和进一步完善,其次才是以教为学,所以如果有些博客写的较简陋,是为了保持进度不得已而为之,还请大家多多见谅。
预:看到题目后的思路和实现的代码。
见:参考答案展示。
感思:对比答案后的思考,与之前做过的题目是否有关联。
行:
(1)对于没做出来的题目,阅读答案后重新做一遍;
(2)下次做题可以尝试改善的方向;
(3)有助于理解的相关的题目
优先级:做题进度>学习&总结>默写回顾>做题数量
为什么使用链表?
链表相对于数组的优势在于其便于插入和删除,而数组存储在连续的地址中,全部替换才能达到“删除”效果。
为什么链表便于插入和删除/时间复杂度n(1)?
与链表的存储和获取下一链表的方式有关。因为链表的存储是不连续的,而数组则是连续存储,链表其通过指针来获取下个节点的位置,所以只需要直接修改指针域则能够插入和删除指针。
链表的定义:链表结构中有指针域和val,val存储对于值,通过指针域来连接下个节点,单链表只有next,而双链表的指针域还有pre。
如何使用链表?
类似数组的创建形式:ListNode 名称 = new ListNode();
题目链接: 203. 移除链表元素
给你一个链表的头节点
head
和一个整数val
,请你删除链表中所有满足Node.val == val
的节点,并返回 新的头节点 。输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]提示:
- 列表中的节点数目在范围
[0, 104]
内1 <= Node.val <= 50
0 <= val <= 50
- class Solution {
- public ListNode removeElements(ListNode head, int val) {
- ListNode dummyNode = new ListNode();
- dummyNode.next = head;
- ListNode pre = dummyNode;
- ListNode cur = dummyNode.next;
- while(cur != null){
- if(cur.val == val){
- pre.next = cur.next; // pre.next.next = pre.next;
- }else{ // 没有否定,直接后面增加pre = pre.next;
- pre = cur;
- }
- cur = cur.next;
- }
- return dummyNode.next;
- }
- }
- ListNode dummyNode = new ListNode();
- dummyNode.next = head;
上面的代码块能够通过直接调用构造函数实现
ListNode dummyNode = new ListNode(-1,head);
链表的定义+链表实现相关操作类
- class ListNode{
- int val;
- ListNode next;
- public ListNode(){
-
- }
- public ListNode(int val){
- this.val = val;
- }
- }
- class MyLinkedList {
- ListNode head = new ListNode();
- int len = 0;
- public MyLinkedList() {
- }
-
- public int get(int index) {
- if(index < 0 || index >= len){
- return -1;
- }
- ListNode cur = head.next;
- while(index != 0 && cur != null){
- cur = cur.next;
- index--;
- }
- return cur.val;
- }
-
- public void addAtHead(int val) {
- addAtIndex(0,val);
- }
-
- public void addAtTail(int val) {
- addAtIndex(len,val);
- }
-
- public void addAtIndex(int index, int val) {
- if(index < 0){
- index = 0;
- }else if(index > len){
- return;
- }
- ListNode cur = head.next;
- ListNode pre = head;
- ListNode temp = new ListNode(val);
- while(index != 0 && cur != null){
- cur = cur.next;
- pre = pre.next;
- index--;
- }
- temp.next = cur;
- pre.next = temp;
- len++;
- }
-
- public void deleteAtIndex(int index) {
- if(index < 0 || index >= len){
- return;
- }
- ListNode cur = head;
- while(index != 0 && cur.next != null){
- cur = cur.next;
- index--;
- }
- cur.next = cur.next.next;
- len--;
- }
- }
1.定义中少了构造器初始多属性的方法
- class ListNode{
- public ListNode(int val,ListNode next}{
- this.val = val;
- this.next = next;
- }
- }
- class MyLinkedList {
- int len;
- ListNode head;
- public MyLinkedList() {
- head = new ListNode(0);
- len = 0;
- }
2. 能够直接通过改动变量+前节点变量直接添加新变量
- public void addAtIndex(int index, int val) {
- ListNode pre = head;
- for(int i = 0;i < index;i++){
- pre = pre.next;
- }
- ListNode toAdd = new ListNode(val);
- toAdd.next = pre.next; //可能会空指针报错
- pre.next = toAdd;
- len++;
- }
- class Solution {
- public ListNode reverseList(ListNode head) {
- // ListNode dummyNode = new ListNode(-1,head);
- ListNode pre = null;
- ListNode cur = head;
- ListNode temp = null;
- while(cur != null){
- temp = cur.next;
- cur.next = pre;
- pre = cur;
- cur = temp;
- }
- return pre;
- }
- }
二刷:思考10分钟,感觉总是画不出循环遍历的闭环。
看完题解总结后,重新思考一下子就顺着题解写出来,但对于当时为什么画不出来就想不到了。
所以,当思考后做不出来时,要将画的思路图拍照或写下来的形式记录下来,因为问题是顽固的。
三刷:
看到这题就想到要画出来再实现,前面10分钟画出来的有问题,之后找到的正确画法(如下图),但仍实现有问题,就在纠结是否是顺序问题。
有问题代码如下
- class Solution {
- public ListNode reverseList(ListNode head) {
- ListNode dummyNode = new ListNode();
- dummyNode.next = head;
- ListNode pre = dummyNode;
- ListNode cur = head;
- ListNode temp = head;
- while(temp.next != null){
- temp = temp.next;
- cur.next = pre;
- pre = cur;
- cur = temp;
- }
- return cur;
- }
- }
实现代码中是dummyNode指向head,并不是如图上面的head指向dummyNode;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。