代码随想录算法训练营day03 | LeetCode 203/707/206
基础知识
数据结构初始化
// 链表节点定义
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
总结
- 题目空间复杂度要求不高就造内存
- 解题思路关键步骤的代码如何实现要在敲代码前明确 解题思路关键步骤的代码如何实现要在敲代码前明确 解题思路关键步骤的代码如何实现要在敲代码前明确
- 链表节点操作模拟要画图
- 自定义一个数据类型,如链表等,要考虑属性 元素个数 、构造器
- 链表删除 虚拟头结点next指针指向原链表 pre + p 双指针删除 特别是配合索引删除 p移动 pre也要移动
- 如何使用计数器实现定位
常用变量名增量更新
size、val、ans、cnt
代码随想录算法训练营day03 | LeetCode 203/707/206的更多相关文章
- 【算法训练营day4】LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表II
[算法训练营day4]LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表 ...
- 【算法训练营day7】LeetCode454. 四数相加II LeetCode383. 赎金信 LeetCode15. 三数之和 LeetCode18. 四数之和
[算法训练营day7]LeetCode454. 四数相加II LeetCode383. 赎金信 LeetCode15. 三数之和 LeetCode18. 四数之和 LeetCode454. 四数相加I ...
- 【算法训练营day1】LeetCode704. 二分查找 LeetCode27. 移除元素
[算法训练营day1]LeetCode704. 二分查找 LeetCode27. 移除元素 LeetCode704. 二分查找 题目链接:704. 二分查找 初次尝试 看到题目标题是二分查找,所以尝试 ...
- 【算法训练营day8】LeetCode344. 反转字符串 LeetCode541. 反转字符串II 剑指Offer05. 替换空格 LeetCode151. 翻转字符串里的单词 剑指Offer58-II. 左旋转字符串
[算法训练营day8]LeetCode344. 反转字符串 LeetCode541. 反转字符串II 剑指Offer05. 替换空格 LeetCode151. 翻转字符串里的单词 剑指Offer58- ...
- 【算法题 14 LeetCode 147 链表的插入排序】
算法题 14 LeetCode 147 链表的插入排序: 解题代码: # Definition for singly-linked list. # class ListNode(object): # ...
- 代码随想录第十三天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素
第一题150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. ...
- 代码随想录第八天 |344.反转字符串 、541. 反转字符串II、剑指Offer 05.替换空格 、151.翻转字符串里的单词 、剑指Offer58-II.左旋转字符串
第一题344.反转字符串 编写一个函数,其作用是将输入的字符串反转过来.输入字符串以字符数组 s 的形式给出. 不要给另外的数组分配额外的空间,你必须原地修改输入数组.使用 O(1) 的额外空间解决这 ...
- Leetcode题解 - 链表简单部分题目代码+思路(21、83、203、206、24、19、876)
- Manacher算法学习笔记 | LeetCode#5
Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...
- 程序员进阶之算法练习:LeetCode专场
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由落影发表 前言 LeetCode上的题目是大公司面试常见的算法题,今天的目标是拿下5道算法题: 题目1是基于链表的大数加法,既考察基本 ...
随机推荐
- 【Java SE】课程目录
〇.课程简介 一.前言入门 二.数据类型.运算符.方法 三.流程控制 四.Idea.方法 五.数组 六.类.对象.封装.构造 七.Scanner类.Random类.ArrayList类 八.Strin ...
- python重要内置模块
目录 包的概念 包的具体使用 编程思想的转变 常用内置模块之collections模块 (收集) 常用内置模块之time模块 (时间) 常用内置模块之random模块 (随机) os模块 sys模块 ...
- kernel 启动流程
一.概述 之前学习了uboot的启动流程,现在接着学习uboot的启动流程,关于 kernel 的启动流程分析的大佬也是很多的,这里还是通过流程的图的方式进行记录,为了像我一样的新手,直观的了解 ke ...
- Vue 响应式原理模拟以及最小版本的 Vue的模拟
在模拟最小的vue之前,先复习一下,发布订阅模式和观察者模式 对两种模式有了了解之后,对Vue2.0和Vue3.0的数据响应式核心原理 1.Vue2.0和Vue3.0的数据响应式核心原理 (1). ...
- Python 文件操作(IO 技术)
目录 Python 文件操作(IO 技术) 文本文件和二进制文件 文件操作相关模块概述 建文件对象 open() 文本文件的写入 write()/writelines()写入数据 close()关闭文 ...
- python之路35 MySQL 3 字段的约束条件 外键关系
字段约束条件 无符号.零填充 unsigned id int unsigned zerofill id int(5) zerofill 非空 create table t1( id int, name ...
- Java入门及环境搭建
1.JAVA三大版本 JAVASE(标准版:桌面程序开发.控制台开发...) JAVAME(嵌入式:手机程序.小家电...) JAVAEE(企业级:web端.服务器开发...) 2.开发环境 JDK: ...
- 请务必注意精度不一样,就不相等(float 与double)
即使两个小数显示的值是一样的,但是类型不一要样,精度不一样实际上是不一样的 就比如下面这段代码: #include <iostream> #include <cstring> ...
- 解决angular11打包报错Type 'Event' is missing the following properties from type 'any[]': ...Type 'Event' is not assignable to type 'string'
出现这种情况,需要检查一下以下事项 1.ts类型声明和html里写的是否一致 1.1举例如下,子组件代码需要注意事项,子组件调用父组件方法,点击传参给父组件,在父组件触发一些时间,当前this指向是父 ...
- 分布式协议与算法-Quorum NWR
1.强一致性与最终一致性 1.1强一致性 强一致性能保证写操作完成后,任何后续访问都能读到更新后的值:强一致性可以保证从库有与主库一致的数据.如果主库突然宕机,我们仍可以保证数据完整.但如果从库宕机或 ...