不得不说,周末要去考软考了,有点小慌张。天气冷了,早上起床好难受啊!!
主要内容
- 单例模式的实现方式
- 滑动窗口算法解leetcode[3]Longest Substring Without Repeating Characters
单例模式的实现方式
我能想到的单例模式的实现方式一共有5中:
- 懒汉式
- 饿汉式
- 双重锁判断机制实现单例
- 静态内部类实现
- 枚举类实现
懒汉式单例模式
public class Singleton {
/**
* 类初始化时,不初始化这个对象(延时加载)
*/
private static Singleton instance;
/**
* 构造器私有化
*/
private Singleton(){}
/**
* 方法同步,效率低
* @return
*/
public static synchronized Singleton getSingleton(){
if(instance==null){
instance=new Singleton();
}
return instance;
}
}
优点:
- 可以实现延时加载
- 线程安全
缺点: - 效率不高
饿汉式单例模式
public class Singleton {
/**
* 类初始化时,就初始化这个对象
*/
private static Singleton instance=new Singleton();
/**
* 构造器私有化
*/
private Singleton(){}
public static Singleton getSingleton(){
return instance;
}
}
优点:
- 线程安全
- 调用效率搞
缺点: - 不能实现延时加载
双重锁判断机制实现单例
public class Singleton {
/**
* 类初始化时,不初始化这个对象,延迟加载
*/
private static Singleton instance;
/**
* 构造器私有化
*/
private Singleton(){}
/**
* 双重锁机制,调用效率有所提高
* @return
*/
public static Singleton getSingleton(){
if(instance==null){
synchronized (Singleton.class){
if (instance==null){
instance=new Singleton();
}
}
}
return instance;
}
}
优点:
- 延迟加载
- 调用效率较高
缺点: - 因为JVM底层的原因,偶尔会出问题
静态内部类实现单例模式
public class Singleton {
/**
* 静态内部类
*/
private static class SingletonClassInstance{
private static final Singleton INSTANCE=new Singleton();
}
/**
* 构造器私有化
*/
private Singleton(){}
public static Singleton getInstance(){
return SingletonClassInstance.INSTANCE;
}
}
优点:
- 线程安全
- 调用效率高
- 可以实现延迟加载
使用枚举类实现单例模式
public enum Singleton {
//枚举元素本身就是单例
INSTANCE;
/**
* 可以添加自己需要的操作
*/
public void operation(){
}
}
优点:
- 线程安全
- 调用效率高
- 能够天然的放置反射和反序列化调用
缺点:
- 不能实现延迟加载
滑动窗口算法解leetcode[3]Longest Substring Without Repeating Characters
题目描述
Given a string, find the length of the longest substring without repeating characters.
Example 1:
Input: “abcabcbb”
Output: 3
Explanation: The answer is “abc”, with the length of 3.
Example 2:
Input: “bbbbb”
Output: 1
Explanation: The answer is “b”, with the length of 1.
Example 3:
Input: “pwwkew”
Output: 3
Explanation: The answer is “wke”, with the length of 3.
Note that the answer must be a substring, “pwke” is a subsequence and not a substring.
解题思路
使用两个指针l,r来标识区间[l,r]为滑动窗口。
并且使用一个数组来记录窗口内字符出现的次数,整个数组充当了map的角色
最初窗口大小是0的,右指针向右扩展,直到右边的字符已经在窗口中出现了,这个时候我们让左指针向右拓展(窗口在缩小)直到窗口内没有重复的字符串。
代码:
class Solution {
public int lengthOfLongestSubstring(String s) {
char[] chars=s.toCharArray();
//用来记录窗口内部,字符的出现的次数,充当map的角色
int[] freq=new int[256];
int l=0; //窗口左侧下标
int r=-1; //窗口右侧下标
int res=0;
while(l<chars.length){
//窗口右侧的元素,纳入窗口,窗口中的元素不会出现重复
//窗口就向右侧扩张
if((r<s.length()-1)&&freq[chars[r+1]]==0){
++r;
freq[chars[r]]++;
}else{
//窗口右侧的元素,在窗口中已经出现了,则从左侧收缩窗口
freq[chars[l]]--;
l++;
}
res=Math.max(res,r-l+1);
}
return res;
}
}