写点什么

ARTS 打卡第二周

作者:苏籍
  • 2023-08-26
    北京
  • 本文字数:4698 字

    阅读完需:约 15 分钟

`

导读: 算法是全排列相关,选取了常见且典型的三个全排列相关算法。
复制代码


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 语法上的优势


一、在封装性上的改进

  1. Modules, 是 jar 包,在这些 jar 里面一些包是被限制访问的,用于保护一些内部代码不被任意访问

文章讲的比较概略,可以参考这个文章

如果没有module,每个public类或成员都可以自由地被其他类使用——无法控制某些内容只在 JAR 中可见而不越界。 甚至非public可见性也不是真正的威慑力,因为总能用反射来访问私有 API。归根于 JAR 本身并没有界限,它们只是类加载器从中加载类的容器。
module是不同的,它们确实具有编译和运行时能够识别的界限。 只有以下情况才能使用module中的类型:
1. 该类型是public的(和以前一样)
2. exports这个包
3. 调用的module 声明了requires此module
这意味着module的创建者可以更好地控制哪些类型将构成public API。 不再是所有,现在是导出包中的所有public类型。
复制代码
  1. sealed class 密封类, 限定可以继承的类的范围,不用导致类或者接口被无节制继承或者实现

语法


sealed class 类名 permits 子类{}
复制代码

每个被允许的子类都需要使用修饰符来描述如何往下传递密封行为。

一共有 3 种选择:

  1. final 修饰的类:声明为 final 来禁止继续继承

final 子类 类名 extends 父类{}
复制代码


  1. 子类声明自己是密封类:声明为 sealed 以同样的方式来限制继承

sealed class 类名 extends 父类 permits 子类{}

  1. 子类声明自己不再是一个密封类了:声明为 non-sealed 来恢复开放继承

non-sealed class 类名 extends 父类{}

详细可以参考:https://blog.csdn.net/crushb/article/details/124594379


二、代码简洁性

  1. 本地变量引用 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));    }}
复制代码
  1. 文本块语法,比如想要多行文本输出,以前需要加入\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    }}
复制代码


  1. 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    }}
复制代码

三、类型转换

  1. 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 }}
复制代码


  1. 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 clonegit pushgit add 、git commitgit checkoutgit pull


管理分支

删除本地分支:git branch -D 本地分支名称 (强删本地分支)

删除远程分支:git push origin --delete 远程分支名称

从当前分支新建一个分支,并切换到这个新建分支上 git checkout -b 新分支名称


更改分支名称

git branch -m 旧名字 新分支名字


放弃本次合并内容,回到合并前状态

git merge --abort


强推 git push -f

Share

最近有些焦虑,关于年龄关于职级关于未来的发展,缠绕在我的思绪中。

看了吴军的一篇文章,分享一下里面的观点


大多数人晋升速度没有达到自己的期望。主要有两个原因

  1. 期望过高。 主要是坑位太少,名额有限,同事都有竞争力。尤其在大厂,短期晋升慢是常态

  2. 陷入职业发展的误区

  3. 工作和职业分不清。 对应的是 Job 和 Profession。

工作是大家谋生的手段,完成任务,公司给钱,能做到专业尽责。

职业则是自己一辈子要从事的事业,如果我们确定自己当前做的工作是一辈子要从事的职业,那么就应该有选择的做事情。做对职业发展有益处的事情。对有害的尽可能不做。

2、把自己仅仅当做一个单位的过客,而不是主人。把公司当做跳板,过客心态,对于一些事情和工作以及同事的关系就不会投入和上心,容易不上进。浪费了时间和锻炼的机会

3、容易被语言暴力激怒,乱了章法。 语言暴力 就是批评责备你,但是不给具体的问题和由建设的建议,不是真心帮助你。 这种情况需要合理应对。要区分出善意的批评建议,方法是善意的批评 采纳后会对自己的工作成长有利,语言暴力则是无理取闹。

对于识别出来语言暴力,对于无意的要明确给他们指出来,对于玩权术的老手,要防范,不轻易反击,尽量化解,事情过了之后,通过正常渠道 让他们直到你已经识破了他的语言暴力

4、疏于沟通。 对于合作的事项,要提前打招呼,有不同意见可以协调、谈判解决,只要有利益可以分配,无非是设法确保各方利益。避免因怕对方不合作 事先不沟通,一厢情愿认为对方会拒绝,容易事与愿违。


解决误区的方案

  1. 任何时候都要谦卑。 可以有效沟通,态度谦卑,但是有自己的看法以及对问题事情的分析

  2. 用正确的方法对待语言暴力和其他不公平

  3. 反省自己,是否有过失,是否把事情想歪了。如果不是搞清楚对方的目的。可以主动沟通,和发声。即便我们大度,也要发声让对方知道他们的问题,沟通中保持尊重,但是态度坚决明确

  4. 要明确自己的工作 是为了自己职业发展的大方向,走出一亩三分地,主动多去学习、打交道、支持同事。可以留下什么遗产

  5. 注重长期效益,把一件事情放到两三年时间周期看待。也许有不一样视野和态度


对于不舒适的环境,如果又可以学习成长的地方,抱着学习的心态也可以委屈,但是对自己的进步毫无用处,那么即使再有光环也应该早点离开


用户头像

苏籍

关注

还未添加个人签名 2019-01-30 加入

还未添加个人简介

评论

发布
暂无评论
ARTS打卡第二周_算法_苏籍_InfoQ写作社区