`
导读: 算法是全排列相关,选取了常见且典型的三个全排列相关算法。
复制代码
Algorithm
全排列
排列:从 n 个元素 中选取 m 个不同数的元素,按照一定顺序排成一列 ( 1=<m<=n)
如果 m=n 表示要选取 所有的数 ,即全排列
解题思路:
回溯的思想,采用递归方式。
第一层面临 n 种选择,第二层面临 n-1 种选择(第一层选择的元素不再进行选择)依次类推直到找到一个全排列为止
class Solution {
List<List<Integer>> result=new ArrayList<>();
public List<List<Integer>> permute(int[] nums) {
if(nums==null||nums.length==0)return result;
// 选择次数是nums.length 一个数只能选择 一次,nums 中的所有整数 互不相同
// 全排列,然后进行剪枝。剪枝的时机是 每次选择 选过的不能再选择了
permuteHelper(nums,new ArrayList(),new boolean[nums.length]);
return result;
}
public void permuteHelper(int[] nums, List<Integer> path, boolean[] visit){
if(path.size()==nums.length){
result.add(new ArrayList<>(path));
return;
}
// 每次做所有的选择,然后进行剪枝
for(int i=0;i<=nums.length-1;i++){
// 当前层 如果访问过就不需要再访问了
if(visit[i])continue;
path.add(nums[i]);
visit[i]=true;
permuteHelper(nums, path,visit);
path.remove(path.size()-1);
visit[i]=false;
}
}
}
复制代码
全排列 II
https://leetcode.cn/problems/permutations-ii/submissions/
class Solution {
List<List<Integer>> result=new ArrayList<>();
public List<List<Integer>> permuteUnique(int[] nums) {
permuteUniqueHelper(nums,new boolean[nums.length],new ArrayList<>());
return result;
}
public void permuteUniqueHelper(int[] nums , boolean[] visit,List<Integer> curLevel){
if(curLevel.size()==nums.length){
result.add(new ArrayList<>(curLevel));
return;
}
// 记录当前每一层选择过的元素,当前层如果选择了a,下次就不要选择a了, 记录是层
Set<Integer> curElement=new HashSet<>();
// 每次做所有的选择,然后进行剪枝
for(int i=0;i<nums.length;i++){
// visit 每次面临的选择,如果上一层选择过了的元素,当前层不再进行选择
if(visit[i])continue;
if(curElement.contains(nums[i])) continue;
curElement.add(nums[i]);
curLevel.add(nums[i]);
visit[i]=true;
permuteUniqueHelper(nums,visit,curLevel);
visit[i]=false;
curLevel.remove(curLevel.size()-1);
}
}
}
复制代码
下一个排列
题解:https://leetcode.cn/problems/next-permutation/solutions/80560/xia-yi-ge-pai-lie-suan-fa-xiang-jie-si-lu-tui-dao-/
Review
Java 17 language compared to Java 8. How modern Java is better than Java 8?
https://marian-caikovski.medium.com/java-17-language-compared-to-java-8-how-modern-java-is-better-than-java-8-65a4e39c448e
文章主要讲 Java17 语言的优势,并且呼吁从 Java8 升级到 Java17.
Java17 是将会被 oracle 长期支持的一个版本
从 Java8->Java17 历经了 8 年
Java17 在性能上有了较大提升,不过本文作者着重讲了 Java17 语法上的优势
一、在封装性上的改进
Modules, 是 jar 包,在这些 jar 里面一些包是被限制访问的,用于保护一些内部代码不被任意访问
文章讲的比较概略,可以参考这个文章
如果没有module,每个public类或成员都可以自由地被其他类使用——无法控制某些内容只在 JAR 中可见而不越界。 甚至非public可见性也不是真正的威慑力,因为总能用反射来访问私有 API。归根于 JAR 本身并没有界限,它们只是类加载器从中加载类的容器。
module是不同的,它们确实具有编译和运行时能够识别的界限。 只有以下情况才能使用module中的类型:
1. 该类型是public的(和以前一样)
2. exports这个包
3. 调用的module 声明了requires此module
这意味着module的创建者可以更好地控制哪些类型将构成public API。 不再是所有,现在是导出包中的所有public类型。
复制代码
sealed class 密封类, 限定可以继承的类的范围,不用导致类或者接口被无节制继承或者实现
语法
sealed class 类名 permits 子类{}
复制代码
每个被允许的子类都需要使用修饰符来描述如何往下传递密封行为。
一共有 3 种选择:
final 修饰的类:声明为 final 来禁止继续继承
子类声明自己是密封类:声明为 sealed 以同样的方式来限制继承
sealed class 类名 extends 父类 permits 子类{}
子类声明自己不再是一个密封类了:声明为 non-sealed 来恢复开放继承
non-sealed class 类名 extends 父类{}
详细可以参考:https://blog.csdn.net/crushb/article/details/124594379
二、代码简洁性
本地变量引用 Var
当编译器可以识别右边值的类型时候,可以用 var 代替具体冗长的强类型
public class LocalVariableTypeInference {
public static void main(String[] args) throws IOException {
List<Set<Integer>> listOfGenerics = List.of(Set.of(1, 2), Set.of(2, 3), Set.of());
try (var bw = Files.newBufferedWriter(Path.of("test.txt"))) {
for (var set : listOfGenerics) {
bw.write(set.toString());
}
}
}
}j
复制代码
2. switch 表达式优化
不再使用 break 或者显示 return,可以直接用表达式处理
public class SwitchExpressions {
static String dayType(int dayOfWeek) {
return switch (dayOfWeek) {
case 1, 2, 3, 4, 5 -> "workday";
case 6, 7 -> "weekend";
default -> throw new RuntimeException("Invalid day");
};
}
public static void main(String[] args) {
System.out.println(dayType(1));
System.out.println(dayType(7));
}
}
复制代码
文本块语法,比如想要多行文本输出,以前需要加入\n 现在可以直接定义即可
public class TextBlocks {
static String textBlock = """
one
two
three""";
static String ordinaryString=" one\n" +
" two\n" +
" three";
public static void main(String[] args) {
System.out.println(textBlock);
System.out.println(ordinaryString);
System.out.println(textBlock.equals(ordinaryString)); // false
}
}
复制代码
record 类
Java record 是一种类,其唯一目的是使用不可变数据驱动编程
文章里写的比较简略,可以参考这篇文章
会自动创建 equals(), hashcode() and toString(),内部不提供 getter 和修改方法,是一个不可变的数据载体
public class RecordsTest {
public static void main(String[] args) {
// record是一个关键字 ,属性不能被修改
record Point(int x, int y){}
System.out.println(new Point(1, 2)); // Point[x=1, y=2]
System.out.println(new Point(1, 2).equals(new Point(1, 2))); //true
}
}
复制代码
三、类型转换
instanceof 优化,在比较类型同时,如果满足条件 可以直接强转给一个变量
public class PatternMatchingWithInstanceof {
static Integer increment(Object o) {
if (o instanceof Integer i) {
return ++i;
}
if (o instanceof String s) {
return Integer.parseInt(s) + 1;
}
throw new RuntimeException("unknown type");
}
public static void main(String[] args) {
System.out.println(increment(1)); // 2
System.out.println(increment("10")); //11
}
}
复制代码
Switch 类型加强,原来只支持 number、string 和枚举类,现在可以支持 Type 名称以及 null
public class PatternMatchingInSwitch {
static Integer increment(Object o) {
return switch (o) {
case Integer i -> ++i;
case String s -> Integer.parseInt(s) + 1;
default -> throw new RuntimeException("unknown type");
};
}
public static void main(String[] args) {
System.out.println(increment(1)); // 2
System.out.println(increment("10")); //11
}
}
复制代码
Tips
Git 常用命令
基本原理:
Git 常用的是以下 6 个命令:git clone、git push、git add 、git commit、git checkout、git pull
管理分支
删除本地分支:git branch -D 本地分支名称 (强删本地分支)
删除远程分支:git push origin --delete 远程分支名称
从当前分支新建一个分支,并切换到这个新建分支上 git checkout -b 新分支名称
更改分支名称
git branch -m 旧名字 新分支名字
放弃本次合并内容,回到合并前状态
git merge --abort
强推 git push -f
Share
最近有些焦虑,关于年龄关于职级关于未来的发展,缠绕在我的思绪中。
看了吴军的一篇文章,分享一下里面的观点
大多数人晋升速度没有达到自己的期望。主要有两个原因
期望过高。 主要是坑位太少,名额有限,同事都有竞争力。尤其在大厂,短期晋升慢是常态
陷入职业发展的误区
工作和职业分不清。 对应的是 Job 和 Profession。
工作是大家谋生的手段,完成任务,公司给钱,能做到专业尽责。
职业则是自己一辈子要从事的事业,如果我们确定自己当前做的工作是一辈子要从事的职业,那么就应该有选择的做事情。做对职业发展有益处的事情。对有害的尽可能不做。
2、把自己仅仅当做一个单位的过客,而不是主人。把公司当做跳板,过客心态,对于一些事情和工作以及同事的关系就不会投入和上心,容易不上进。浪费了时间和锻炼的机会
3、容易被语言暴力激怒,乱了章法。 语言暴力 就是批评责备你,但是不给具体的问题和由建设的建议,不是真心帮助你。 这种情况需要合理应对。要区分出善意的批评建议,方法是善意的批评 采纳后会对自己的工作成长有利,语言暴力则是无理取闹。
对于识别出来语言暴力,对于无意的要明确给他们指出来,对于玩权术的老手,要防范,不轻易反击,尽量化解,事情过了之后,通过正常渠道 让他们直到你已经识破了他的语言暴力
4、疏于沟通。 对于合作的事项,要提前打招呼,有不同意见可以协调、谈判解决,只要有利益可以分配,无非是设法确保各方利益。避免因怕对方不合作 事先不沟通,一厢情愿认为对方会拒绝,容易事与愿违。
解决误区的方案
任何时候都要谦卑。 可以有效沟通,态度谦卑,但是有自己的看法以及对问题事情的分析
用正确的方法对待语言暴力和其他不公平
反省自己,是否有过失,是否把事情想歪了。如果不是搞清楚对方的目的。可以主动沟通,和发声。即便我们大度,也要发声让对方知道他们的问题,沟通中保持尊重,但是态度坚决明确
要明确自己的工作 是为了自己职业发展的大方向,走出一亩三分地,主动多去学习、打交道、支持同事。可以留下什么遗产
注重长期效益,把一件事情放到两三年时间周期看待。也许有不一样视野和态度
对于不舒适的环境,如果又可以学习成长的地方,抱着学习的心态也可以委屈,但是对自己的进步毫无用处,那么即使再有光环也应该早点离开
评论