Java写算法题中那些影响你效率的细节(关于暴力破解算法题的细节处理)
QQ讨论群:99979568 多交流才能进步
暂时写到这里,有不懂的欢迎评论, 如果有什么其他提高效率的细节,欢迎评论或者私信我,小编一定努力学习,争取早日分享给大家
如果大家嫌三连累的话,可以看看这个文章,快速三连(●ˇ∀ˇ●)
判断奇数偶数
两个变量的值交换
在使用数组长度的时候需要注意
做OJ或者控制台输入时可以优化的地方 求质数的方法(欧拉筛)
循环中一定不能进行的操作
循环中一定要会的操作(goto语句)
声明变量需要注意的地方
if条件中的boolean应该怎么判断才能提高效率
在使用List,Map,Set时需要注意的事情
long,double类型的正确声明
在数组中最大值和最小值差值比较小的时候,推荐使用的排序
判断奇数偶数
正常情况下,我们都是去对2取模看是不是奇数偶数
package CSDN_Demo;
public class 奇数偶数篇 {
public static void main(String[] args) {
int n = 20;
if(n % 2 == 0) {
System.out.println("是偶数");
} else {
System.out.println("是奇数");
}
}
}
PS:注意:光理论是不够的,在此送大家一套2020最新Java架构实战教程+大厂面试题库 点击此处 进来获取 ,希望大家一起进步哦!
实际上,位运算的效率会更高
package CSDN_Demo;
public class 奇数偶数篇 {
public static void main(String[] args) {
long start1 = System.currentTimeMillis();
for (int m = 0; m <= 1000; m++) {
if (m % 2 == 0) {
System.out.println("是偶数");
} else {
System.out.println("是奇数");
}
}
long end1 = System.currentTimeMillis();
long start2 = System.currentTimeMillis();
for (int n = 0; n <= 1000; n++) {
if ((n & 1) == 0) {
System.out.println("是偶数");
} else {
System.out.println("是奇数");
}
}
long end2 = System.currentTimeMillis();
System.out.println("正常的时间为" + (end1 - start1));
System.out.println("位运算的时间为" + (end2 - start2));
}
}
控制台的结果显示如下:
一个数&1 == 1 证明是奇数 一个数&1 == 0 证明是偶数
两个变量的值交换
当两个变量值需要交换的时候,我们通常情况下是声明一个变量当作中介去交换
其实我们也可以进行位运算,(●ˇ∀ˇ●)
package CSDN_Demo;
public class 两个变量的交换 {
public static void main(String[] args) {
int a = 21, b = 35;
long start1 = System.currentTimeMillis();
int c;
for (int m = 0; m <= 1000; m++) {
a = 21;
b = 35;
c = a;
a = b;
b = c;
System.out.println("a:" + a + "b:" + b);
}
long end1 = System.currentTimeMillis();
long start2 = System.currentTimeMillis();
for (int n = 0; n <= 1000; n++) {
a = 21;
b = 35;
a ^= b;
b ^= a;
a ^= b;
System.out.println("a:" + a + "b:" + b);
}
long end2 = System.currentTimeMillis();
System.out.println("正常的时间为" + (end1 - start1));
System.out.println("位运算的时间为" + (end2 - start2));
}
}
结果图如下
位运算是不是很恐怖 ヽ(*。>Д<)o゜
此时a和b是需要交换的变量
a ^= b;
b ^= a;
a ^= b;
只需要进行这三步操作即可交换变量的值
在使用数组长度的时候需要注意
我们在使用数组长度的时候尽量少使用数组.length
如果真的需要使用的话,我们可以用一个变量去代替数组.length
package CSDN_Demo;
public class 尽量不使用数组的长度 {
public static void main(String[] args) {
int[] num = new int[1000];
long start1 = System.currentTimeMillis();
for (int m = 0; m < num.length; m++) {
System.out.println(num.length);
}
long end1 = System.currentTimeMillis();
long start2 = System.currentTimeMillis();
int len = num.length;
for (int n = 0; n < len; n++) {
System.out.println(len);
}
long end2 = System.currentTimeMillis();
System.out.println("使用数组.length的时间为" + (end1 - start1));
System.out.println("不使用数组.length的时间为" + (end2 - start2));
}
}
效果图如下:
效果很明显,不过多解释了(小编是直男癌晚期患者,实在编不下去了,,下一个)
做OJ或者控制台输入时可以优化的地方
如果我们接收的是字符串的话,完全可以用IO,效率杠杠滴,不信的话,自己找个OJ测试一下,(不要被效率惊吓到(●ˇ∀ˇ●))
使用IO一定要加上try,catch或者throws标明异常
package CSDN_Demo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class String字符串控制台输入 {
public static void main(String[] args) throws IOException {
InputStreamReader r=new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(r);
String s = br.readLine();
br.close();
r.close();
System.out.println(s);
}
}
如果是字符串需要按照空格分开的话,小编了解有一个StringTokenizer类,可以结合IO很好的使用接收字符串(这里又把IO压缩了一下)
package CSDN_Demo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class String字符串控制台输入 {
public static void main(String[] args) throws IOException {
//实例化StringTokenizer对象(只传一个参数是按照空格分隔) 匿名压缩IO接收的
StringTokenizer stringTokenizer = new StringTokenizer((new BufferedReader(new InputStreamReader(System.in))).readLine());
//和迭代器一样,判断有没有下一个,有的话就循环输出
while (stringTokenizer.hasMoreTokens()) {
System.out.println(stringTokenizer.nextToken());
}
//这里再提供一下StringTokenizer的另一个构造方法
//public StringTokenizer(String str,String delim,boolean returnDelims)
//str - 要解析的字符串。
//delim - 分隔符。
//returnDelims - 指示是否将分隔符作为标记返回的标志。
}
}
如果你接受的int值,我建议还是用Scanner吧,io接收的int是一个数字一个数字接收,并且是按照ASCII的值来接受的
package CSDN_Demo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class 控制台输入 {
public static void main(String[] args) throws IOException {
InputStreamReader r=new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(r);
int a = br.read();
int b = br.read();
//用完了记得关闭(两个都关上最好,提高效率)
br.close();
r.close();
System.out.println(a);
System.out.println(b);
}
}
效果图
Tips:
无论你使用哪种接受方法,输入接收完毕后,最好关闭输入流,提高效率
输入流.close();
求质数的方法(欧拉筛)
小编不过多解释了,自己慢慢缕一缕就懂了
package CSDN_Demo;
import java.util.Arrays;
public class 欧拉筛求质数 {
public static void main(String[] args) {
//传入的参数是求n以内的质数
int[] num = getPrime(1000);
for (int i : num) {
System.out.println(i);
}
}
//欧拉筛 不过多解释了,自己慢慢缕一缕
public static int[] getPrime(int n) {
int[] list = new int[n + 1];
int[] prime = new int[n + 1];
int count = 0;
for (int i = 2; i <= n; i++) {
if (list[i] == 0) prime[count++] = i;
for (int j = 0; j < count && i * prime[j] <= n; j++) {
list[prime[j] * i] = 1;
}
}
return Arrays.copyOf(prime, count);
}
}
循环中一定不能进行的操作
这里没有Demo了,在for循环中最好不要声明变量,数组之类的,声明变量或者实例化,一定要放在循环外面,否则会很影响效率的;
循环中一定要会的操作(goto语句)
goto语句在一定程度上是真的好用,Demo也没有举太好的例子,
goto语句:其实就是转移运行的语句
package CSDN_Demo;
public class Goto语句 {
public static void main(String[] args) {
//Demo并不是很好,大概举个例子,大家就凑活看一下吧
//这里求前i项的和>10000时的i
int sum=0;
A:
for (int i = 1; i < 1000; i++) {
sum =0;
for (int j = 1; j < i; j++) {
sum += j;
if(sum > 10000) {
System.out.println(i);
break A;
}
}
}
}
}
可以看,在我写的时候,就直接跳过了A;
使用goto语句还可以把循环类似递归用,我们也可以continue A;来跳过本次循环
声明变量需要注意的地方
声明变量的时候,最好不要用封装类型,因为在使用的过程中可能因为拆箱解箱导致效率下降
另外正常情况下,封装类型时引用类型,但在Integer中范围在-128~127之中是值类型
,需要注意
如果可以用byte就不要用int,如果可以用boolean就不要用byte
遵循用小字节的特点,省内存,其实boolean和byte差不多,Boolean在判断上有优势的
if条件中的boolean应该怎么判断才能提高效率
很多人判断if中的boolean变量还在写
boolean bool = true;
if (bool == true)
其实这里的话,我们用
if (bool) 比较好,如果是取反的话,我们直接用if (!bool)
在使用List,Map,Set时需要注意的事情
List我们经常使用的是:ArrayList和LinkendList
这个ArrayList是数组构成的,所以在遍历的时候会快一些,
LinkendList是链表构成的,所以在增删的时候会快一些
自己结合情况使用,增删多就用LinkendList,遍历多就用ArrayList
Map和Set如果又排序需求的话就用TreeSet或者TreeMap,
如果没有排序需求的话,我建议用HashSet或者HashMap,
Hash在平常情况下使用确实会比其他的快很多
long,double类型的正确声明
我们平常声明long类型的时候,
long temp = 123;
其实这样的话,我们声明的还是int变量
正常的话应该是
long temp = 123L;(其实这里小写的l也行,但是小写的 l
容易和 1
混淆)
double类型也一样
double temp = 123.0D
在数组中最大值和最小值差值比较小的时候,推荐使用的排序
package CSDN_Demo;
public class 差值小的数组排序 {
public static void main(String[] args) {
//这里举得例子可能小了点,但这种排序对于数组中最大值和最小值差值小的都比较好用
int[] num = {1, 2, 3, 5, 2, 1, 4, 5, 6, 8, 1, 2, 3, 5, 4, 9, 7};
int min = num[0];
int max = num[0];
int len = num.length;
for (int i = 0; i < len; i++) {
min = Math.min(num[i], min);
max = Math.max(num[i], max);
}
//数组大小为最大值减去最小值
int[] temp = new int[max - min + 1];
for (int i = 0; i < len; i++) {
//使用当前值与最小值的差当作下标
temp[num[i] - min]++;
}
len = max - min + 1;
for (int i = 0; i < len; i++) {
while (temp[i] != 0) {
System.out.print((i + min)+" ");
temp[i]--;
}
}
}
}
PS:注意 最后 送大家一套2020最新Java架构实战教程+大厂面试题库, 点击此处 进来获取 ,希望大家一起进步哦!
Java写算法题中那些影响你效率的细节(关于暴力破解算法题的细节处理)的更多相关文章
- select语句中会影响查询效率的因素
1.没有创建索引,或者没有正确使用索引;2.存在死锁的情况,从而导致select语句挂起; 3.返回不必要的列,如很多人喜欢在程序中使用select * from 这样会查询表或视图中的所有字段,如果 ...
- 【经验】 Java BigInteger类以及其在算法题中的应用
[经验] Java BigInteger类以及其在算法题中的应用 标签(空格分隔): 经验 本来在刷九度的数学类型题,有进制转换和大数运算,故而用到了java BigInteger类,使用了之后才发现 ...
- Java在算法题中的输入问题
Java在算法题中的输入问题 在写算法题的时候,经常因为数据的输入问题而导致卡壳,其中最常见的就是数据输入无法结束. 1.给定范围,确定输入几个数据 直接使用普通的Scanner输入数据范围,然后使用 ...
- 用Java写算法之归并排序
转自:http://flyingcat2013.blog.51cto.com/7061638/1281026 前面的三种排序算法(冒泡排序,选择排序,插入排序)在平均情况下均为O(n^2)复杂度,在处 ...
- 8.算法竞赛中的常用JAVA API :Calendar日期类
8.算法竞赛中的常用JAVA API :Calendar日期类 摘要 在蓝桥杯中有关于日期计算的问题,正好java中的Date类和Calendar类提供了对日期处理的一些方法.Date类大部分方法已经 ...
- Java基础知识强化之网络编程笔记09:TCP之客户端键盘录入服务器写到文本文件中
1. TCP之客户端键盘录入服务器写到文本文件中 (1)客户端: package cn.itcast_09; import java.io.BufferedReader; import java.io ...
- 算法竞赛中的常用JAVA API:PriorityQueue(优先队列)(转载)
算法竞赛中的常用JAVA API:PriorityQueue(优先队列) PriorityQueue 翻译过来就是优先队列,本质是一个堆, 默认情况下堆顶每次都保留最小值,每插入一个元素,仍动态维护堆 ...
- 算法竞赛中的常用JAVA API :HashSet 和 TreeSet(转载)
算法竞赛中的常用JAVA API :HashSet 和 TreeSet set set容器的特点是不包含重复元素,也就是说自动去重. HashSet HashSet基于哈希表实现,无序. add(E ...
- 算法竞赛中的常用JAVA API :HashMap 和 TreeMap(转载)
算法竞赛中的常用JAVA API :HashMap 和 TreeMap 摘要 本文主要介绍Map接口下的HashMap和TreeMap. HashMap HashMap是基于哈希表的 Map 接口的实 ...
随机推荐
- 【Hadoop离线基础总结】oozie调度shell脚本
目录 1.解压官方提供的调度案例 2.创建工作目录 3.拷贝任务模板到工作目录当中去 4.随意准备一个shell脚本 5.修改模板下的配置文件 6.上传调度任务到hdfs上面去 7.执行调度任务 1. ...
- R语言:日薪和应发工资
生产部门普通员工为日薪,有时要知道日薪和应发工资的转换关系.做表一为日薪取整数,白天工资+晚上工资=应发工资,延长工作时间取时薪的1.5倍,应发工资保留到十位.做表二为应发工资取十的倍数,推算相应日薪 ...
- Oracle JDK究竟从哪个版本开始商用收费?
经常被问到Oracle JDK是不是要钱了?收费了?从哪个版本开始商用收费? 木有错,Oracle JDK从2019年4月16号开始商用商用商用收费了!有图有真像: 2019年4月16日当天,Orac ...
- DP之石子堆合并问题
相邻 环形 总结 (1)相邻:在一个圆形操场的四周摆放着n堆石子(n<= 100),现要将石子有次序地合并成一堆.规定每次只能选取相邻的两堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得 ...
- chrom浏览器总是将http请求强制转换成https请求
chrome://net-internals/#hsts 中 Delete domain security policies 输入该站点,将将该站点删除一下就OK. 其他浏览器: Chrome 浏览器 ...
- dede文章列表根据权重自定义排序
首先在这里说明一下,网上搜索织梦文章列表自定义的方式无非有以下几种: 1.修改配置文件,新增一个orderid字段,想法很好,但是!但是!!!可能是早期版本的缘故,不适合现在的v5.7系统!按照网上说 ...
- Docker学习笔记(二):端口映射与容器互联
端口映射 使用docker run时,可以指定-P(大写)与-p(小写)参数映射端口. docker run -P -P(大写)会随机映射一个端口到容器的内部端口 -> [feifei@ffma ...
- webpack指南(一)HRM+Tree Shaking
参考:https://www.cnblogs.com/PasserByOne/p/12084323.html https://blog.csdn.net/qq593249106/article/det ...
- context的简单应用
数据上传 context.setAttribute protected void doGet(HttpServletRequest req, HttpServletResponse resp) thr ...
- APIView中的dispatch
(1)dispatch方法详解----封装原有的request对象 (原request中的方法和属性均可直接在封装后的request中调用,或者使用request._request也可,如:reque ...