基础知识

数据结构初始化

// 链表节点定义
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;
}
} // 单链表定义
class ListNode {
int val;
ListNode next;
ListNode(){}
ListNode(int val) {
this.val=val;
}
}
class MyLinkedList {
//size存储链表元素的个数
int size;
//虚拟头结点
ListNode head; //初始化链表
public MyLinkedList() {
size = 0;
head = new ListNode(-1);
}
} // 双链表定义
class ListNode{
int val;
ListNode next,prev;
ListNode() {};
ListNode(int val){
this.val = val;
}
} class MyLinkedList { //记录链表中元素的数量
int size;
//记录链表的虚拟头结点和尾结点
ListNode head,tail; public MyLinkedList() {
//初始化操作
this.size = 0;
this.head = new ListNode(-1);
this.tail = new ListNode(-2);
//这一步非常关键,否则在加入头结点的操作中会出现null.next的错误!!!
head.next=tail;
tail.prev=head;
}
}

LeetCode 203

分析1.0

删除链表节点,①考虑空表特殊情况直接返回 ②ans为新链表头节点,第一个val不满足的节点即为头节点 ③删除节点过程, 相等删除节点,不等则p指针后移

/**
* 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;
}
// 构建虚拟头结点
int cnt = 1;
ListNode ans = new ListNode(-1), p = new ListNode();
p.next = head;
while(p.next != null){
if(p.next.val == val){
p.next = p.next.next;
continue;
}
if(p.next.val != val){
if(cnt == 1){
ans = p.next;
cnt = 0;
}
p = p.next;
}
}
return ans.val==-1 ? null : ans;
}
}

分析2.0

上面的分析只使用了一个p指针,而新的头结点是计算出来的,并不是统一计算而来。

改进:

设置cur、pre指针,设置虚拟头结点virtualHead

相等时删除 不等时后移

收获:① 使用多个指针简化思维难度 ②新建节点时可以直接将head作为参数传进去

ListNode virtualHead = new ListNode(-1, head);
ListNode pre = virtualHead;
ListNode cur = head;
while (cur != null) {
if (cur.val == val) {
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
return virtualHead.next;

LeetCode 707

分析1.0

乍一看有点懵,题目给出的条件有点少,光给个构造器,其他怎么啥也没有,属性呢???我链表的头结点咋办呢???要我自己定义节点吗???

我用内部类定义了Node节点,出了点问题,mark一下:

内部类 

待总结!!! 留个坑

delete报错

public void deleteAtIndex(int index) {
ListNode pre = new ListNode(-1);
ListNode p = head;
pre.next = p;
int cnt = 1;
if(index > 0 && index <= size)
while(cnt <= index){
pre = p;
p = p.next;
pre.next = p;
cnt++;
}// 考虑只有一个元素,要删除第一个元素的特殊情况 用虚拟节点
System.out.println("cnt:" + cnt);
System.out.println("p指针:" + p.val);
log();
pre.next = p.next;
p = pre.next;
this.size--;
}

分析2.0

看了解析,意识到LinkeList的属性应该设置哪些

难点 delete

public void deleteAtIndex(int index) {
if (index < 0 || index >= size) {
return;
}
size--;
if (index == 0) {
head = head.next;
return;
}
ListNode pred = head;
for (int i = 0; i < index ; i++) {
pred = pred.next;
}
pred.next = pred.next.next;
}

LeetCode 206

分析1.0

反转链表,第一个节点和最后一个节点互换位置,第二个节点和倒数第二个节点互换位置 ...  一共n个元素 则互换 n/2 次 ,这是二分的思路

class Solution {
public ListNode reverseList(ListNode head) {
// 指定虚拟头结点
ListNode p = new ListNode(-1,head);
int num = 0;
while(p.next != null){
p.next = p.next.next;
num++;
}
// 打印信息 判断p位置
System.out.println(num);
System.out.println(p.val);
for(int i = 0; i<= num/2; i++){
}
return head;
}
}

失误 

从后往前的节点该怎么遍历呢?虽然可以用计数器确定循环终止条件,但是链表和数组不一样,不能实现随机访问

注意 ①将思路变为代码的过程极为重要,在写之前就要弄清楚关键步骤的代码如何实现

分析2.0

灵光一现,可以遍历的时候采用尾插法将节点添加到末尾 qiao

class Solution {
public ListNode reverseList(ListNode head) {
if(head == null){
return head;
}
// 指定虚拟头结点
ListNode ret = new ListNode(-1);
// 遍历指针
ListNode p = head,temp;
while(p != null){
temp = p.next;
p.next = ret.next;
ret.next = p;
//System.out.println(p.val);
p = temp;
}
return ret.next;
}
}

这题没这么复杂,一开始就不要想偏,误入歧途真的很难顶

注意

① 画图分析节点的插入过程 ② 节点next指向新节点后就不是原来的那个节点了

分析3.0

我的思路被头结点局限住了,头结点是可以变化的,指针反向,新的头结点就是原来的最后一个节点 o(╥﹏╥)o

总结

  1. 题目空间复杂度要求不高就造内存
  2. 解题思路关键步骤的代码如何实现要在敲代码前明确 解题思路关键步骤的代码如何实现要在敲代码前明确 解题思路关键步骤的代码如何实现要在敲代码前明确
  3. 链表节点操作模拟要画图
  4. 自定义一个数据类型,如链表等,要考虑属性 元素个数 、构造器
  5. 链表删除 虚拟头结点next指针指向原链表 pre + p 双指针删除 特别是配合索引删除 p移动 pre也要移动
  6. 如何使用计数器实现定位

常用变量名增量更新

size、val、ans、cnt

 
 
 

代码随想录算法训练营day03 | LeetCode 203/707/206的更多相关文章

  1. 【算法训练营day4】LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表II

    [算法训练营day4]LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表 ...

  2. 【算法训练营day7】LeetCode454. 四数相加II LeetCode383. 赎金信 LeetCode15. 三数之和 LeetCode18. 四数之和

    [算法训练营day7]LeetCode454. 四数相加II LeetCode383. 赎金信 LeetCode15. 三数之和 LeetCode18. 四数之和 LeetCode454. 四数相加I ...

  3. 【算法训练营day1】LeetCode704. 二分查找 LeetCode27. 移除元素

    [算法训练营day1]LeetCode704. 二分查找 LeetCode27. 移除元素 LeetCode704. 二分查找 题目链接:704. 二分查找 初次尝试 看到题目标题是二分查找,所以尝试 ...

  4. 【算法训练营day8】LeetCode344. 反转字符串 LeetCode541. 反转字符串II 剑指Offer05. 替换空格 LeetCode151. 翻转字符串里的单词 剑指Offer58-II. 左旋转字符串

    [算法训练营day8]LeetCode344. 反转字符串 LeetCode541. 反转字符串II 剑指Offer05. 替换空格 LeetCode151. 翻转字符串里的单词 剑指Offer58- ...

  5. 【算法题 14 LeetCode 147 链表的插入排序】

    算法题 14 LeetCode 147 链表的插入排序: 解题代码: # Definition for singly-linked list. # class ListNode(object): # ...

  6. 代码随想录第十三天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素

    第一题150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. ...

  7. 代码随想录第八天 |344.反转字符串 、541. 反转字符串II、剑指Offer 05.替换空格 、151.翻转字符串里的单词 、剑指Offer58-II.左旋转字符串

    第一题344.反转字符串 编写一个函数,其作用是将输入的字符串反转过来.输入字符串以字符数组 s 的形式给出. 不要给另外的数组分配额外的空间,你必须原地修改输入数组.使用 O(1) 的额外空间解决这 ...

  8. Leetcode题解 - 链表简单部分题目代码+思路(21、83、203、206、24、19、876)

  9. Manacher算法学习笔记 | LeetCode#5

    Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...

  10. 程序员进阶之算法练习:LeetCode专场

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由落影发表 前言 LeetCode上的题目是大公司面试常见的算法题,今天的目标是拿下5道算法题: 题目1是基于链表的大数加法,既考察基本 ...

随机推荐

  1. JS笔记合集之对象

    对象 对象基本使用 对象是JS中的一种复合数据类型,它相当于一个容器,在对象中可以存储各种不同类型的数据 而基本数据类型(原始值)只能存储一些简单的数据,如: 语法: 原始创建对象: let obj ...

  2. 乐维监控与Zabbix对比分析(一)——架构、性能

    近年来,Zabbix凭借其近乎无所不能的监控及优越的性能一路高歌猛进,在开源监控领域独占鳌头:而作为后起的新锐监控平台--乐维监控,则不断吸收Zabbix,Prometheus等优秀开源平台的优点,兼 ...

  3. 【书籍知识回顾与总结-2022】Java语言重点知识-多线程编程、流式编程

    一.多线程编程 二.流式编程 1.目的 简化集合和数组的操作 注意:每个流只能使用一次 2.获取流的方式 (1)单列集合:stream方法 KeySet()/values()/EntrySet() ( ...

  4. SpringBoot源码2——SpringBoot x Mybatis 原理解析(如何整合,事务如何交由spring管理,mybatis如何进行数据库操作)

    阅读本文需要spring源码知识,和springboot相关源码知识 对于springboot 整合mybatis,以及mybatis源码关系不密切的知识,本文将简单带过 系列文章目录和关于我 涉及到 ...

  5. 聚焦技术,锐意创新,GaussDB给世界一个更优选择

    摘要:从整个行业应用层面来看,现在,数据库的国产化时代已经到来. 本文分享自华为云社区<聚焦技术,锐意创新,GaussDB给世界一个更优选择>,作者: GaussDB数据库. 今天,以&q ...

  6. java中的静态属性和静态方法

    本文主要讲述java的静态变量和静态方法 静态变量和静态方法,随着类加载完成,而完成,随着类的消失,而销毁. 静态方法只能调用静态变量/方法:普通方法,既能调用静态变量/方法,也能调用非静态变量/方法 ...

  7. vue项目封装 axios 和 api

    一,utils文件夹下新建一个request.js文件 import axios from 'axios'; import QS from 'qs'; import { Toast } from 'v ...

  8. ssm——mybatis整理

    目录 1.mybatis框架概述 2.直接使用jdbc连接数据库带来的问题 3.mybatis连接池 3.1.mybatis连接池yml配置 3.2.mybatis连接池xml配置 4.一个简单的my ...

  9. [常用工具] C++环境下Qt的安装

    文章目录 1 Qt(C++)版本的选择 2 Qt 安装 2.1 Qt 6.3.1的安装 2.2 Qt 5.14.2的安装 3 Qt 其他版本安装 1 Qt(C++)版本的选择 Qt(C++)是一个跨平 ...

  10. 官网下载CentOS系统镜像过程

    想学习CentOS系统,但是不知道镜像去哪里搞,随便去个第三方发现要么要注册,要么各种广告病毒,或者好不容易找到官网,不仅全英文,有些专业术语也不懂,本文说明官网下载自己想要的CentOS镜像整个流程 ...