每日总结Day4(不知道能坚持几天)


12.2

操作系统作业+HTML作业 14:20-18:00


没想到做这么久,对了中间还睡了一觉来着,emmm还是挺久的,下次直接cv


力扣18:00-20:10

记录一下哪些题自己能独立写出来,√表示能做,×表示不能

希望有一天我一天也能刷几十道,不像这样磕磕绊绊

1094. 拼车 中等


  1. 算是暴力做出来的吧,改了很多次
  2. 思路:先按照起始地从小到大进行排序,然后用Map来记录终点和对应的人数,如果下一站的时候有终点在这个新站的起点之前的,就给取出来更新left
public static boolean carPooling(int[][] trips, int capacity) {
int left = capacity;
Arrays.stream(trips).sorted(new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[1] - o2[1];
}
}).collect(Collectors.toList()).toArray(trips);
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < trips.length; i++) {
int nums = trips[i][0];
int from = trips[i][1];
int to = trips[i][2];
for (int j = 0; j <= from; j++) {
if (map.get(j) != null) {
left += map.get(j);
map.remove(j);
}
}
if (left < nums) return false;
left -= nums;
map.put(to, map.getOrDefault(to,0)+nums);
}
return true;
}


× 300. 最长递增子序列 中等


  1. 没做出来,想到了dp[i]用来表示前i之前的最大递增子序列的大小,但是没有把递推公式写出来
public static int lengthOfLIS(int[] nums) {
//dp[i]表示以i为结尾的最大子序列长度
int[] dp = new int[nums.length];
int res = 1;
Arrays.fill(dp, 1);
for (int i = 1; i < nums.length; i++) {
for (int j = 0; j < i; j++) {
if (nums[i] > nums[j]) {
//含义:如果nums[i]>nums[j]
// 那么dp[i]的最大子序列长度肯定是比dp[j]的最大子序列长度+1
//因为每个dp i会遍历[0-i)内的dp[j] 所以肯定是取一个最大的dp[i]
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
res = Math.max(dp[i], res);
}
return res;
}


674. 最长连续递增序列 简单


  1. 这道题和上一道题类似,但是不用重新遍历dp来取最大值,只需要取dp[i-1]的值(因为是连续的) 也能用双指针来做,双指针好理解一点 都是 O(n)
/**
* 时间复杂度 On
*
* @param nums
* @return
*/
public int findLengthOfLCIS(int[] nums) {
//dp[i]表示0-i元素内的最长递增子序列的长度
int[] dp = new int[nums.length];
//默认为0
int res = 0;
for (int i = 1; i < nums.length; i++) {
// for (int j = i - 1; j < i; j++) {
// if (nums[i] > nums[j]) {
// dp[i] = dp[j] + 1;
// }
// }
if (nums[i] > nums[i - 1]) dp[i] = dp[i - 1] + 1;
res = Math.max(res, dp[i]);
}
//因为初始的时候为0,像2,3这个算的是一个,所以要+1
return res + 1;
}
/**
* 双指针
*
* @param nums
* @return
*/
public int findLengthOfLCIS2(int[] nums) {
int res = 1;
int left = 1;
int right = nums.length;
int count = 1;
while (left < right) {
if (nums[left] > nums[left - 1]) {
count++;
} else {
count = 1;
}
left++;
res = Math.max(res, count);
}
return res;
}



设计模式 8:27-10:00

单例设计模式


  1. 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例, 并且该类只提供一个取得其对象实例的方法(静态方法)。
  2. 比如 Hibernate 的 SessionFactory,它充当数据存储源的代理,并负责创建 Session 对象。SessionFactory 并不是 轻量级的,一般情况下,一个项目通常只需要一个 SessionFactory 就够,这是就会使用到单例模式。


懒汉式(单线程推荐)

懒汉式静态常量


  1. 优点:这种写法比较简单,就是在类装载的时候就完成实例化。避免了线程同步问题。
  2. 缺点:这个类可能不会被用上,那么就会造成资源的浪费,没有达到懒加载的效果
  3. 懒加载:用到的时候才创建
  4. 总结:可以用,但是可能会造成内存资源的浪费。如果确定每个类一定会被使用到,那么可以使用这种方式
class Singleton {
//1. 构造器私有化, 外部能 new
private Singleton() {
}
//2.本类内部创建对象实例
private final static Singleton instance = new Singleton();
//3. 提供一个公有的静态方法,返回实例对象
public static Singleton getInstance() {
return instance;
}
}



懒汉式静态代码块


  1. 和懒汉式的静态常量模式一样,也是会在类装载的时候创建对象
  2. 其余见懒汉式静态常量
class Singleton {
//1. 构造器私有化, 外部能 new
private Singleton() {
}
//2.本类内部创建对象实例
private static Singleton instance;
static { // 在静态代码块中,创建单例对象
instance = new Singleton();
}
//3. 提供一个公有的静态方法,返回实例对象
public static Singleton getInstance() {
return instance;
}
}



饿汉式

饿汉式(线程不安全)


  1. 虽然起到了懒加载的效果,但是线程不安全了
  2. 很多线程同时进行不为空的判断,都通过了,那么就会返回多个实例,违反了单例
  3. 仅在单线程下使用
  4. 多线程不能使用!!
class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}



饿汉式(同步方法)


  1. 为getInstance()方法加上同步,只能有一个线程执行该方法
  2. 虽然解决了线程不安全的问题,但是每次只能有一个方法执行,大大降低了系统性能,不可取!
class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}



饿汉式(同步代码块)


  1. 还是不可取的一个方法!
  2. 分析:当有多个线程通过了if的判断在等待同步方法执行结束再创建实例,这样也是创建了多个实例,违反了单例模式
  3. class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if(instance == null) {
synchronized (Singleton.class){
instance = new Singleton();
}
}
return instance;
  1. }


双重检查(推荐)


  1. volatile 可以理解为一个轻量的同步的措施
  2. 分析:当有多个n个线程通过了第一个if的判断后,都进入到第二个if那里排队等待,只有一个线程能够进入然后生成实例,这个时候剩下的n-1个线程才排队进入同步快判断,解决了线程安全的问题,也提高了系统性能,最多只会影响n个线程
class Singleton {
private static volatile Singleton instance;
private Singleton() {
}
//提供一个静态的公有方法,加入双重检查代码,解决线程安全问题, 同时解决懒加载问题
//同时保证了效率, 推荐使用
public static synchronized Singleton getInstance() {
if(instance == null) {
synchronized (Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}



静态内部类(推荐)


  1. 这种方式采用了类装载的机制(JVM的特性保证线程安全)来保证初始化实例时只有一个线程
  2. 静态内部类方式在 Singleton 类被装载时并不会立即实例化,而是在需要实例化时,调用 getInstance 方法,才 会装载 SingletonInstance 类,从而完成 Singleton 的实例化
  3. 类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM 帮助我们保证了线程的安全性,在类进行 初始化时,别的线程是无法进入的
// 静态内部类完成, 推荐使用
class Singleton {
//构造器私有化
private Singleton() {}
//写一个静态内部类,该类中有一个静态属性 Singleton
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
//提供一个静态的公有方法,直接返回 SingletonInstance.INSTANCE
public static synchronized Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}



枚举(推荐)


  1. 这借助 JDK1.5 中添加的枚举来实现单例模式。不仅能避免多线程同步问题,而且还能防止反序列化重新创建 新的对象。
  2. 这种方式是 Effective Java 作者 Josh Bloch 提倡的方式
enum Singleton {
INSTANCE; //属性
}



锻炼10:20-11:10


久违的锻炼,之前10月份跑步跑伤了之后,10月11月就只有断断续续的跑,跑了一会儿就开始有点不舒服,现在都不敢跑多了,今天跑下来没有啥感觉,应该好的差不多了,后面开始加点速度,慢慢来

今日内容:

  1. 4km慢跑

  1. 俯卧撑20+15+15,25+15+10 总100
  2. 仰卧起坐20




总结11:55


今天起来就是10:30了,999还是太猛了,昨天睡的也挺早,按平时应该最多9点就能醒的,然后磨磨蹭蹭的到中文家里送衣服过来,然后又带了些饭菜,吃完之后就1:30了,然后我又去洗了一下衣服啥的,最后两点才出门(其实要不是我想到昨天我写的计划,真就在寝室玩了今天)

然后那两个作业做的太久了,html我本来想自己做的,然后最后一个作业一直没做出来花了挺久时间,该直接cv的(最后还是cv的)

然后到饭点,实在是想到没学到啥,然后就没去吃饭了,直接开始做题!!

跑步的时候是真的爽,以前是强迫自己为了减肥而跑步,现在真的是享受这个过程,和我同学一起跑一遍分享以前的故事,跑着都没啥感觉,也不累啥的哈哈哈哈哈哈

还有昨天计划的突击蓝桥杯等明天来了,起得太晚,做那个作业做的太久了,明天一定!

今天过得大概就是这样拉~~


明日计划

  1. 看一下我以前写的力扣题目,复习一下常用的API以及思路(我做题都在本地开了一个项目来存放,然后给提交到gitee上,感觉这样比较有成就感哈哈哈

冲刺一个12月全勤!(希望)

  1. 力扣继续!
  2. 设计模式,明天保底学两种!
  3. java面试题两道!

准备睡了~~~


0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
EWAN
下载 APP