基础知识

数据结构初始化

// 链表节点定义
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. C++编程笔记(QT)

    目录 入门基础 模态对话框 消息提示框(messagebox) 文件和目录 字体选择框 输入对话框 进度条 工具栏 控件布局 Windows托盘案例 控件 button 下拉菜单按钮 `radioBu ...

  2. 4.5:HDFS操作实验

    〇.概述 1.拓扑结构 2.目标 进行HDFS的实验,了解HDFS的基本操作. 一.常用操作 1.启动 50070 2.查看及创建 3.上传文件

  3. python 中文分词工具

    python 中文分词工具 jieba,https://github.com/fxsjy/jieba jieba_fast,https://github.com/deepcs233/jieba_fas ...

  4. <五>模板的完全特例化和非完全特例化

    模板作为C++泛型编程的基础十分重要,其使得一份代码能用于处理多种数据类型.而有些时候,我们会希望对一些特定的数据类型执行不同的代码,这时就需要使用模板特例化(template specializat ...

  5. echarts map地图中绘制浙江省市区县乡镇多级联动边界下钻的最新geojson数据文件获取和更新

    目录 ECharts Map地图的显示 GeoJSON数据文件获取 在ECharts中绘制浙江省的数据 ECharts Map地图的显示 ECharts支持地理坐标显示,专门提供了一个geo组件,在s ...

  6. Hexo+next主题美化

    前言 需要在Hexo下配置next主题 Hexo配置next主题教程:https://www.cnblogs.com/xuande/p/16641543.html 更改配置以后使用素质三连:hexo ...

  7. http转成https工具类

    工具类代码如下: 点击查看代码 package com.astronaut.auction.modules.oss.utils; import org.apache.commons.collectio ...

  8. npm Error: Cannot find module 'are-we-there-yet'

    npm 损坏了,are-we-there-yet是npm所依赖的npmlog依赖的一个包,重新安装npm即可 踩坑,直接安装还是报错,不管执行哪个命令都是报下面这个错 网上百度了很多,有的说把node ...

  9. 【转载】SQL SERVER 中单字节和双字节互转自定义函数(全角半角转换)

    一.首先创建一个自定义函数,代码如下: alter function f_convert( @str nvarchar(4000), --要转换的字符串 @flag bit --转换标志,0转换成半角 ...

  10. CH334、CH335USB2.0Hub芯片(更新ing)

    USB HUB又称USB集线器,主要用于USB主机端口扩展,广泛应用于计算机,笔记本,及周边应用.CH334.CH335是符合 USB2.0 协议规范的高性能MTT 4 端口 USB2.0  HUB  ...