剑指offer学习心得(一天二题,坚持更新。。。)

今年12月份研究生毕业,六月份将去实习,但深感自己编程能力的不足,很是恐慌。逛了各大论坛发现大家都在说剑指offer这本书。抱着死马当活马医的态度开始刷题,一天三道题,首先用java过一遍,如有富余时间再用python过一遍。
除了发上源码以外还有些自己的心得和一些自己觉得比较重要的知识点,望各位大神多多指正!

第一题:设计一个类,我们只能生成该类的一个实例。

预备知识:
(1)单例模式(Singleton):单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在。

(2)修饰符
1.private 私有的

private 关键字是访问控制修饰符,可以应用于类、方法或字段(在类中声明的变量)。 只能在声明 private(内部)类、方法或字段的类中引用这些类、方法或字段。在类的外部或者对于子类而言,它们是不可见的。 所有类成员的默认访问范围都是 package 访问,也就是说,除非存在特定的访问控制修饰符,否则,可以从同一个包中的任何类访问类成员。
简而言之:类的属性变量及方法,只有在本类中可以访问。

  1. protected 受保护的

protected 关键字是可以应用于类、方法或字段(在类中声明的变量)的访问控制修饰符。可以在声明 protected 类、方法或字段的类、同一个包中的其他任何类以及任何子类(无论子类是在哪个包中声明的)中引用这些类、方法或字段。所有类成员的默认访问范围都是 package 访问,也就是说,除非存在特定的访问控制修饰符,否则,可以从同一个包中的任何类访问类成员。
简而言之:类的属性变量及方法,在同一个包中的任何类中都可访问。(但包外继承了此类的子类可以访问)

  1. public 公共的

public 关键字是可以应用于类、方法或字段(在类中声明的变量)的访问控制修饰符。 可能只会在其他任何类或包中引用 public 类、方法或字段。所有类成员的默认访问范围都是 package 访问,也就是说,除非存在特定的访问控制修饰符,否则,可以从同一个包中的任何类访问类成员。
简而言之:类的属性变量及方法,包内及包外的任何类均可以访问;

4.default 不用写
简而言之:类的属性变量及方法,只有包内的类可以访问,包外的类不可以访问,且继承的子类也不可访问。

(3)static关键字
static关键字,修饰符

1、修饰属性(如果类中某个属性被修饰为静态的,那么这个属性会被所有类的对象所共有,或者说是不管你创建多少个类的对象,访问的始终是同一个,静态属性必须有个初始值)

public static 数据类型 属性名称=初始值;

操作访问静态属性
a、对象.属性名称
b、类名.属性名称

2、修饰方法(如果某个方法被修饰为静态的,此方法可以直接通过类名调用,静态方法中不能访问非静态的成员属性)
public static 返回值类型 方法名称(形参列表){}

操作访问静态方法
a、对象.方法名称();
b、类名.方法名称();

3、静态块(最先执行并且只执行一次的代码)
static{
语句块;//数据库注册驱动,大量开辟内存空间
}

(4).final关键字

final关键字(修饰符)
1、修饰属性(如果某个属性被修饰为final那么此属性就变成常量)

访问修饰符 final 数据类型 属性名称=初始值;

2、修饰方法(如果某个方法被修饰为final那么此方法是不允许被覆盖(重写))
访问修饰符 final 返回值类型 方法名称(形参列表){
方法体;
}

3、修饰类(如果某个类被修饰为final那么此类不能有子类)
public final class 类名{

}

方法1:

public class Singleton {
private static Singleton instance=new Singleton(); *//private使外部类无法访问,static使其只有一个对象。*
private Singleton() {};*//私有化构造方法,使其在其他类中无法实例化。*

*//public static使得可以使用类名.方法调用getinstance方法。而无需先实例化对象*
public static Singleton getinstance() {
	
	return instance;
}
}
*//有static的初始化,是一个线程只执行一次的,所以方法一线程安全。但由于加载类时就会初始化对象,浪费性能。*

方法2

public class DlaySingleton {
private static DlaySingleton instance;
private DlaySingleton() {};
public static DlaySingleton getinstance() {
	if(instance==null) {
		instance=new DlaySingleton();
	}
	return instance;
}
}
*//此方法是在调用方法的时候实例化对象,而不是在加载类的时候实例化对象,相对于方法1来说性能较优,但可能有多个线程访问代码块,故线程不安全。*
public class InternalClassSingleton {
private InternalClassSingleton() {};
private static class InternalClass {
	private static final InternalClass instance=new InternalClass();//static final修饰
}
public static InternalClass getinstance() {
	return InternalClass.instance;
}
}
*//当调用getinstance方法时,才会加载内部类internalclass和方法二一样性能上得到了保证,加载内部类后直接实例化对象,同方法一相同,保证了线程安全。*

static final用来修饰成员变量和成员方法,可以理解为“全局变量”
(1)对于变量,表示一旦给值就不可修改,并且通过类名可以访问。
(2)对于方法,表示不可覆盖,并且可以通过类名直接访问。
注意:
对于被static和final修饰过的实例常量,实例本身不能再改变了,但对于一些容器类型(比如,ArrayList、HashMap)的实例变量,不可以改变容器变量本身,但可以修改容器中存放的对象。

你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

第二题: 数组中重复的数组:在一个长度为n的数组里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3

public class Excise2 {
	int b;
	int c;
public boolean number(int [] a) {
	if(a==null&&a.length<=0) {//写代码前先考虑异常情况出现,思考要完备,不要一味想着问题怎么去解决。当数组为空或数组长度为0是返回false
		return false;
	}
	
	for(int i=0;i<a.length;i++) {
		if(a[i]>=a.length&&a[i]<0) {
			return false;    //遍历数组,不符合题目条件返回false
		}
		
		while(a[i]!=i) {
			if(a[i]==a[a[i]]) {//解释在下面
				 b=a[i];
				 System.out.println(b);
				 return true;
			}
			c =a[i];
			a[i]=a[c];
			a[c]=c;     //交换不同索引值的位置
			
		}
		
	}
	return false;
}
public static void main(String[] args) {
	Excise2 a=new Excise2();
	int [] b= {8,7,6,5,4,8,3,2,1};
	
	a.number(b);
}
}

运行结果截图
在这里插入图片描述
以数组{2,3,1,0,2,5,3}为例来分析找到重复数字的步骤。数组的第0个数字(从0开始计数,和数组的下标保持一致)是2,与它的下标不相等,于是把它和下标为2的数字1交换,交换后的数组是{1,3,2,0,2,5,3}。此时第0 个数字是1,仍然与它的下标不相等,继续把它和下标为1的数字3交换,得到数组{0,1,2,3,2,5,3}。此时第0 个数字为0,接着扫描下一个数字,在接下来的几个数字中,下标为1,2,3的三个数字分别为1,2,3,他们的下标和数值都分别相等,因此不需要做任何操作。接下来扫描下标为4的数字2.由于它的值与它的下标不相等,再比较它和下标为2的数字。注意到此时数组中下标为2的数字也是2,也就是数字2和下标为2和下标4的两个位置都出现了,因此找到一个重复的数字。
附上参考博文
(https://blog.csdn.net/weixin_37672169/article/details/79978096)

第一次写的博客就到这里了,哈哈哈哈哈哈哈。
明天续更!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值