【算法】数据结构与算法基础总览(中)——刷Leetcode等算法题时一些很实用的jdk辅助方法锦集
最近重新学习数据结构与算法以及刷leetcode算法题时,发现不少jdk自带的方法可以提升刷题的效率。这些小技巧不仅仅对刷算法题带来便利,对我们平时开发也是很有帮助的。本文以java语言为基础,记录了目前已经使用或看到过的一些小技巧,后续在刷题过程中,还会持续更新。
一、数组
1、使用Arrays.sort(int[] a)进行排序
底层采用的是快速排序算法实现的:时间复杂度为O(nlogn),空间复杂度O(logn),不稳定。默认是从小到大排序。
int[] arr = new int[]{2, 9, 6, 8, 4, 3};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
打印结果:
[2, 3, 4, 6, 8, 9]
参数可以是其它基本数据类型,也可以是自定义类型,可以通过使用Comparator比较器来自定义排序顺序。
例如,降序排列:
1 Integer[] arr = new Integer[]{2, 9, 6, 8, 4, 3};
2 Arrays.sort(arr, new Comparator<Integer>() {
3 @Override
4 public int compare(Integer t0, Integer t1) {
5 return t1 - t0;
6 }
7 });
8 System.out.println(Arrays.toString(arr));
打印结果:
[9, 8, 6, 4, 3, 2]
2、使用Arrays.toString(int[] arr)将数组组合成字符串
内部是通过StringBuilder + for 循环来实现的,该方法可以方便调试查看数组的值,而无需自己手动来组装字符串。
int[] arr = new int[]{2, 9, 6, 8, 4, 3};
System.out.println(Arrays.toString(arr));
打印结果:
[2, 9, 6, 8, 4, 3]
同样,该方法的参数数组类型可以是其它数据类型。
3、使用Arrays.fill()一次性给数组填充指定值
有时候我们需要将数组中的所有元素都初始化填充为指定值,一般的做法是通过循环来一一赋值,这样做显然不够简洁。所幸,java sdk中提供了简洁的方法来一步实现,如下所示:
int[] arr = new int[10];
Arrays.fill(arr,1);
System.out.println(Arrays.toString(arr));
打印结果:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
实际上fill()内部实现也是通过for循环一一赋值的,但对开发者使用而言,确实简洁了很多。
二、ArrayList
1、使用构造函数或者addAll将一个集合中的内容添加到新的ArrayList中
//构造函数
public ArrayList(Collection<? extends E> c)
//addAll方法
public boolean addAll(Collection<? extends E> c)
内部实现原理:ArrayList内部维护了一个数组,无论是使用构造函数还是addAll方法,都是将给定集合中的元素复制到该数组中。
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
List<Integer> newList1 = new ArrayList<>(list);
System.out.println(newList1);
List<Integer> newList2 = new ArrayList<Integer>();
newList2.addAll(list);
System.out.println(newList2);
打印结果:
[1, 2, 3]
[1, 2, 3]
2、ArrayList与数组互相转化
(1)使用list.toArray()将ArrayList转为数组
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Object[] a = list.toArray();
System.out.println(Arrays.toString(a));
打印结果:
[1, 2, 3]
(2)使用Arrays.asList(数组) 将数组转为ArrayList
Integer[] arr = new Integer[]{2, 9, 6, 8, 4, 3};
List<Integer> arrList = Arrays.asList(arr);
System.out.println("size=" + arrList.size() + ";arrList=" + arrList);
打印结果:
size=6;arrList=[2, 9, 6, 8, 4, 3]
3、使用Collections.reverse(list) 倒转ArrayList中的元素
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Collections.reverse(list);
System.out.println(list);
打印结果:
[3, 2, 1]
4、使用Set来过滤具有相同元素的list
Set<List<String>> set = new HashSet<>();
List<String> list1 = Arrays.asList("a", "b");
List<String> list2 = Arrays.asList("a", "b");
set.add(list1);
set.add(list2);
System.out.println(list1 == list2);
System.out.println(set);
打印结果:
false
[[a, b]]
从打印结果可知,list1和list2不是同一个对象,但其中包含的元素一样(内容和顺序都一样),Set就只会保存第一个加入的list。目前只发现set中添加的List对象时有这个特性,如果使用数组,或者StringBuilder等引用型对象就不生效,且如果两个list中元素顺序不一致,也不会有过滤效果。
三、HashMap
1、在new HashMap对象时,初始化其中的内容
public Map<String, String> map = new HashMap() {
{
put("k1", "v1");
put("k2", "v2");
}
}; System.out.println(map);
打印结果:
{k1=v1, k2=v2}
使用该方法后,就不用专门在某个方法中通过put来添加内容,无疑,在很多场景下可以带来不少便利。
2、类似于ArrayList类,HashMap也可以通过构造函数或者putAll()方法,一次将已知的hashMap内容添加进来:
//方式一(map为上一节中的对象):
Map<String,String> newMap = new HashMap(map);
//方式二:
Map<String,String> newMap = new HashMap();
newMap.putAll(map); System.out.println(newMap);
打印结果:
{k1=v1, k2=v2}
四、字符串
1、按照多个空格,对字符串进行分割:split(“\\s+”)或者split(" +")
例如:
String s = "leetcode is very good!";
String[] arr = s.split("\\s+"); //或者s.split(" +");
System.out.println(Arrays.toString(arr));
打印结果:
[leetcode, is, very, good!]
2、去掉字符串首尾空字符串:trim()
1 String s = " ab cd ";
2 Sytem.out.println(s.trim());
打印结果:
ab cd
3、拼接字符串:join()
1 String[] strArray = {"ab","cd","ef"};
2 System.out.println(String.join(" ",strArray));
打印结果:
ab cd ef
这里将数组组合成字符串,用“ ”连接。join的第一个参数可以替换其它的连接符号,第二个参数除了使用数组外,还可以使用LIst,Deque等集合对象
五、位运算
机器世界计算和存储最终使用的数据格式都是二进制,采用位运算可以更加贴近机器语言,提高计算效率(当今计算机新能如此强的情况下,一些小范围使用位运算提升的效率看起来肯定是微乎其微,不过使用位运算逼格肯定提升一个档次~~)。
1、判断奇偶
以往判断奇偶采用的都是 x % 2 == 1 和 x % 2 == 0 ,这里我们可以使用&运算来判断:
(x & 1) == 1 // 说明x为奇数
(x & 1) == 0 // 说明x为偶数
例如:
System.out.println("5是奇数吗?:" + ((5 & 1) == 1));
System.out.println("5是偶数吗?:" + ((5 & 1) == 0));
System.out.println("4是奇数吗?:" + ((4 & 1) == 1));
System.out.println("4是偶数吗?:" + ((4 & 1) == 0));
打印结果:
5是奇数吗?:true
5是偶数吗?:false
4是奇数吗?:false
4是偶数吗?:true
2、除以2
以往一个数x除以2的计算方式是x / 2,这里采用位运算的方式为:
x >> 1;//右移1位,表示除以2
x << 1;//左移1位,表示乘以2
例如:
System.out.println(5 >> 1);
System.out.println(5 << 1);
打印结果为:
2
10
(持续完善中......)
【算法】数据结构与算法基础总览(中)——刷Leetcode等算法题时一些很实用的jdk辅助方法锦集的更多相关文章
- NopCommerce开源项目中很基础但是很实用的C# Helper方法
刚过了个五一,在杭州到处看房子,不知道杭州最近怎么了,杭州买房的人这么多,房价涨得太厉害,这几年翻倍翻倍地涨,刚过G20,又要亚运会,让我这样的刚需用户买不起,也买不到房子,搞得人心惶惶,太恐怖了,心 ...
- Python Django中一些少用却很实用的orm查询方法
一.使用Q对象进行限制条件之间 "或" 连接查询 from django.db.models import Q from django.contrib.auth.models im ...
- 解决winform中mdi子窗体加载时显示最大化最小化按钮的方法
场景:在mid加载子窗体的时候如果指定WindowState为Maximized,加载完成后主窗体会显示最大化.最小化.关闭的按钮图标. 解决方法: 1.更改主窗体FormMain的属性.制定Main ...
- CocoaPods中的头文件import导入时不能自动补齐的解决方法
1.选择target(就是左边你的工程target)-->BuildSettings-->search Paths下的User Header Search Paths 2.添加“$(POD ...
- windows中当你的键盘无法使用时我们可以用另一种方法哦
1.使用Win+R打开cmd窗口 2.输入osk回车就出现了一个虚拟的小键盘啦,当你的键盘坏掉后非常实用哦
- 刷oj之类的题时java Scanner读取太慢解决之道
1.转载自一个 https://www.cpe.ku.ac.th/~jim/java-io.html 2.工具代码 class Reader { static BufferedReader reade ...
- 用JavaScript刷LeetCode的正确姿势
虽然很多人都觉得前端算法弱,但其实 JavaScript 也可以刷题啊!最近两个月断断续续刷完了 leetcode 前 200 的 middle + hard ,总结了一些刷题常用的模板代码.走过路过 ...
- 数据结构和算法(Golang实现)(9)基础知识-算法复杂度及渐进符号
算法复杂度及渐进符号 一.算法复杂度 首先每个程序运行过程中,都要占用一定的计算机资源,比如内存,磁盘等,这些是空间,计算过程中需要判断,循环执行某些逻辑,周而反复,这些是时间. 那么一个算法有多好, ...
- 数据结构和算法(Golang实现)(10)基础知识-算法复杂度主方法
算法复杂度主方法 有时候,我们要评估一个算法的复杂度,但是算法被分散为几个递归的子问题,这样评估起来很难,有一个数学公式可以很快地评估出来. 一.复杂度主方法 主方法,也可以叫主定理.对于那些用分治法 ...
随机推荐
- 分享一个的c++写的,模仿awk的框架类CAwkDoc
这是我好多年前,模仿awk写的. awk大家都比较熟悉,使用awk处理文件,读取文件,分割字段这些工作awk自己帮你实现了. 程序员只要编写业务逻辑代码,并且awk还提供了很多常用的字符串操作函数,可 ...
- Hive表的基本操作
目录 1. 创建表 2. 拷贝表 3. 查看表结构 4. 删除表 5. 修改表 5.1 表重命名 5.2 增.修.删分区 5.3 修改列信息 5.4 增加列 5.5 删除列 5.6 修改表的属性 1. ...
- Redis必知必会系列
1.常用命令 https://www.cnblogs.com/huozhonghun/p/11636053.html 2.Redis是什么 Redis 是 C 语言开发的一个开源的(遵从 BSD 协议 ...
- nacos服务注册与发现原理解析
前言:nacos 玩过微服务的想必不会陌生,它是阿里对于springcloud孵化出来的产品,用来完成服务之间的注册发现和配置中心,其核心作用我就不废话了 大致流程:每个服务都会有一个nacos cl ...
- Head First 设计模式 —— 11. 组合 (Composite) 模式
思考题 我们不仅仅要支持多个菜单,升值还要支持菜单中的菜单.你如何处理这个新的设计需求? P355 [提示]在我们的新设计中,真正需要以下三点: P354 我们需要某种属性结构,可以容纳菜单.子菜单和 ...
- LeetCode234 回文链表
请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶:你能否用 O(n) 时间复杂 ...
- Flutter 应用入门:路由管理
路由(Route)在移动开发中通常指页面(Page),这跟web开发中单页应用的Route概念意义是相同的,Route在Android中通常指一个Activity,在iOS中指一个ViewContro ...
- 【Linux】rsh进程缓慢问题处理
环境CentOS 6.5 由于项目上线时间很长,服务器持续很久没有关机重启过,随后发现rsh反应特别慢 rsh登陆服务器的反应最慢时候3分钟才可以建立链接,登陆之后查看服务器负载是否正常,查看cpu, ...
- MSDOS(MBR)和GPT磁盘分区表
MBR和GPT分区 MBR分区:以磁盘的第一个扇区(512byte)记录分区表,其中,446byte存储开机管理程序(MBR 主要开机记录),64byte用于存放分区表 分区实际上是对分区表的修改 M ...
- 浅谈JavaScript代码性能优化
可以通过https://jsbench.me/测试网站完成性能测试. 一.慎用全局变量 1.全局变量定义在全局执行上下文,是所有作用域链的顶端,在局部作用域中没找到的变量都会到全局变量中去查找,所以说 ...