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 接口的实 ...
随机推荐
- Mybatis使用ResultMap
解决字段名和属性名不一致的问题 - 新建数据库表的字段-这里就不贴上了 在下面链接有 https://www.cnblogs.com/rzkwz/p/12853899.html 设置实体类和数据库字段 ...
- 读CSV文件并写arcgis shp文件
一.在这里我用到的csv文件是包含x,y坐标及高程.降雨量数据的文件.如下图所示. 二.SF简介 简单要素模型(Simple Feature,SF),是 OGC 国际组织定义的面向对象的矢量数据模型. ...
- Web快速输入标签
在书写web代码的时候,掌握一些快捷输入方式不仅可以提高效率,还能省不少力气. 1. > :下一个子标签,如 div>p 加Tab达到: <div><p></ ...
- 简述SpringCloud底层原理
目录 一.业务场景介绍 二.Spring Cloud核心组件:Eureka 三.Spring Cloud核心组件:Feign 四.Spring Cloud核心组件:Ribbon 五.Spring Cl ...
- 计算机组成及系统结构-第九章 输入输出(I/O)设备
输入输出(I/O)设备 一.外部设备概述 二.输入设备 1.键盘 2.光笔.图形板和画笔(或游动标)输入 3.鼠标.跟踪球和操作杆输入 4.触摸屏 5.图像输入设备 6.条形码 7.光学字符识别(OC ...
- git init 后关联github仓库是发生错误:
: failed to push some refs to 'git@github.com:AlanKnightly/reactC.git'hint: Updates were rejected be ...
- js性能优化之---防抖函数
使用场景 input的时时触发搜索功能 scroll事件的滚动条位置的监测 resize事件监听窗口变化等 举个栗子(input框时时触发搜索功能) 普通未防抖款 var textElement = ...
- 把iview中的table组件写成了一个公用组件,在另一个组件里去引用它的时候rander函数里的this指向不正确
在vue项目里使用iview制作后台管理系统时,由于有多个页面都需要用到table组件,所以就把table写到了一个公共组件里,在其他页面去引用它,但是这时会发现一个问题,就是render函数里的th ...
- 函数的不同调用方式决定了this的指向不同
一.函数的不同调用方式决定了this的指向不同,一般指向调用者 1.普通函数 this指向window的调用者 function fn(){ console.l ...
- Python 如何随机打乱列表(List)排序
场景: 现在有一个list:[1,2,3,4,5,6],我需要把这个list在输出的时候,是以一种随机打乱的形式输出. 专业点的术语:将一个容器中的数据每次随机逐个遍历一遍. 注意:不是生成一个随机的 ...