剑指Offer 18. 删除链表的节点
给定单链表的头指针和一个要删除的节点值,定义一个函数删除该节点。返回删除后的链表的头节点。
1 | 输入: head = [4,5,1,9], val = 5 |
1 | 输入: head = [4,5,1,9], val = 1 |
1 | class Solution |
我们一路奋战,不是为了改变世界,而是为了不让世界改变我们
1 | 输入: head = [4,5,1,9], val = 5 |
1 | 输入: head = [4,5,1,9], val = 1 |
1 | class Solution |
1 | public class ListNode |
1 | 输入: 1->2->3->4->5->NULL |
1 | class Solution |
1 | class Solutin |
本章将学习面向对象程序设计的另外一个基本概念:继承(inheritance)。继承的基本思想是,可以基于已有的类创建新的类。继承已存在的类就是复用(继承)这些类的方法,而且可以增加一些新的方法和字段,使新类能够适应新的情况。这是Java程序设计中的一项核心技术。
另外,本章还阐述了反射(reflection)的概念。反射是指在程序运行期间更多地了解类及其属性的能力。反射是一个功能强大的特性,不过,不可否认它也相当复杂。
继承主要解决的问题就是:共性抽取。
回忆一下在前一章中讨论过的Employee类。假设你在某个公司工作,这个公司里的经理的待遇与普通员工的待遇存在着一些差异。不过,他们之间也存在着很多相同的地方,例如,他们都领取薪水。只是普通员工在完成本职任务之后仅领取薪水,而经理在完成了预期的业绩之后还能得到奖金。这种情形下就需要使用继承。为什么呢?因为需要为经理定义一个新类Manager,并增加一些新功能。但可以重用Employee类中已经编写的部分代码,并保留原来Employee类中的所有字段。从理论上讲,在Manager与Employee之间存在着明显的“is-a”关系,每个经理都是一个员工:“is-a”关系是继承的一个明显特征。
可以如下继承Employee类来定义Manager类,这里使用关键字extends表示继承。
1 | public class Manager extends Employee |
关键字extends表明正在构建的新类派生于一个已经存在的类。这个已存在的类称为超类(superclass)、基类(base class)
或父类(parent class);新类称为子类(subclass)、派生类(derived class)或孩子类(child class)。
尽管Employee类是一个超类,但并不是因为它优于子类或者拥有比子类更多的功能。实际上恰恰相反,子类比超类拥有更多的功能。
继承关系的特点:
直接通过子类对象访问成员变量:等号左边是谁,就优先用谁,没有则向上找。
间接通过成员方法访问成员变量:方法属于谁,就优先用谁,没有则向上找。
区分子类方法中重名的三种变量:
父类的成员变量:super.成员变量名
面向对象程序设计(object-oriented programming,OOP);面向对象的程序是由对象组成的,每个对象包含对用户公开的特定功能部分和隐藏的实现部分。程序中的很多对象来自标准库,还有一些自定义的。
面向对象三大特征:封装、继承、多态。
类(class)是构造对象的模板或蓝图。由类构造(construct)对象的过程称为创建类的实例(instance)。
封装(encapsulation)是处理对象的一个重要概念。从形式上看,封装就是将数据和行为组合在一个包中,并对对象的使用者隐藏具体的实现方式。对象中的数据称为实例字段(instance field),操作数据的过程称为方法(method)。
实现封装的关键在于,绝对不能让类中的方法直接访问其他类的实例字段。程序只能通过对象的方法与对象数据进行交互。封装给对象赋予“黑盒”特征,这是提高重用性和可靠性的关键。
在扩展一个已有的类时,这个扩展后新类具有被扩展的类的全部属性和方法。你只需要在新类提供适用于这个新类的新方法和数据字段就可以了。通过扩展一个类来建立另外一个类的过程称为继承(inheritance)。
对象的三个主要特性:
在类之间,最常见的关系有:
继承(inheritance)(“is-a”)
三个特殊的浮点类型:
检测一个特定值是否等于Double.NaN:
1 | if (x == Double.NaN)// is never true |
1 | if(Double.isNaN(X)) |
浮点数不适用于无法接受舍入误差的金融计算,可以使用BigDecimal类。
可以利用关键字final 指示常量。关键字final表示这个变量只能被赋值一次,一旦被赋值之后就不能够再更改了;常量使用全大写。
当希望某个常量可以在一个类的多个方法中使用,通常将这些常量称为类常量(class constant);可以使用static final设置一个常量;类常量的定义位于main方法的外部,在同一个类的其他方法也可以使用这个常量。若一个常量被声明为public,那么其他类的方法也可以使用这个常量。
变量的取值只有在一个有限的集合内。
1 | enum Size {SMALL,MEDIUM,LARGE,EXTRA_LARGE}; |
Size类型的变量只能存储这个类型声明中给定的某个枚举值,或是特殊值null。
当一个数组大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方法是:
二维数组转稀疏数组思路:
根据sum创建稀疏数组sparseArr int[sum + 1][3];
将二维数组的有效数据存入到稀疏数组。
稀疏数组转二维数组:
读取稀疏数组后面的几行数据,并赋给原始的二维数组。
$k = \frac {|y’’|}{(1+y’^2)^{\frac{3}{2}}}$
对于一条曲线来说我们可以研究其曲率。通常来想,以一条连续光滑的曲线上无限接近的两个点为端点的一弧线总可以视为是某个圆上的一段弧(可以简单的认为曲率半径在连续光滑的曲线上不会发生突变,所以在某点的无穷小领域内曲率半径可以作为一个常量)。而这个圆的半径就被定义为曲线在这一点的曲率半径,而曲率则被定义为曲率半径的倒数。
那么如何求曲率的半径呢?我们可以回想一下刚接触到弧度制的时候是怎么定义弧度的。弧度是圆弧长与该圆半径的比值,即$\alpha = \frac{S}{R}$;显然当$S=2\pi R$即整个圆周长时弧度为$2\pi$。
那么显然曲率半径很自然的可以定义为$R=\frac{dS}{d\alpha}$,即无穷小的一段弧长与其相对应的弧度的比值。
无线电波是一种电磁波。低频的无线电波不能穿越大气层,只能在地面传播;而高频的无线电波可以穿透大气层的电离层,例如:X光可以穿透人体,生成X光影像;伽马射线产生的电离辐射,就是核武器的杀伤手段之一。不同频率的无线电波表现出来的性质不一样,其实就是一种东西都是电磁波。
生活中常用的无线电波主要在几千Hz~300GHz。根据频率的高低被国际电信联盟(Internationals Telecommunication Union,ITU)规定出各种专用的通信频率,也叫做信道。专业信道涵盖的业务范围特别广,例如:海上移动通信业务,AM广播,FM广播,无线电视广播,太空对地通信,GPS卫星通信服务,深空研究通信,卫星时间校准服务,卫星广播业务服务。