数列排序
这个你至少应该掌握冒泡和快排,以及java自带的方法
//快速排序
public static void quicksort(int[] arr,int low,int high){
int i,j,temp,t;
if(low>high){
return;
}
i=low;
j=high;
//基准也就是最后放到中间的数
temp=arr[low];
while (i<j) {
//先先看右边,依次往左递减
while(temp<=arr[j]&&i<j){
j--;
}
//再看左边,依次往右递增
while(temp>=arr[high]&&i<j){
i++;
}
//如果满足条件则交换
if (i<j) {
t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
//最后将基准为与i和j相等位置的数字交换
arr[low] = arr[i];
arr[i] = temp;
//递归调用左半数组
quicksort(arr, low, j-1);
//递归调用右半数组
quicksort(arr, j+1, high);
}
java快速排序函数有:
Arrays.sort(), 与 Collections.sort(),两种;
区分:
1、对于输入的数据类型(例如int型)如果使用ArrayList定义的,即ArrayList arr = new ArrayList<>(); //ArrayList中无int型,可用Integer代替;
可以用 Collection.sort()方法排序;
2、对于直接用int定义的数组(例:int arr[] = new int [5]);可以用Arrays.sort()方法排序;
进制转换
首先回顾一下转换方法 https://www.cnblogs.com/gaizai/p/4233780.html
java中有一些内置方法
十进制转成十六进制:
Integer.toHexString(int i)
十进制转成八进制
Integer.toOctalString(int i)
十进制转成二进制
Integer.toBinaryString(int i)
十六进制转成十进制
Integer.valueOf(“FFFF”,16).toString()
八进制转成十进制
Integer.valueOf(“876”,8).toString()
二进制转十进制
Integer.valueOf(“0101”,2).toString()
转化为指定位数
https://blog.csdn.net/wahaha13168/article/details/83008252
但是算法中的数字极大而long类型才十九位无法使用
//2进制转为10进制
private static String toOctal(String strBinary) {
int len = strBinary.length();
int k;
StringBuffer stb = new StringBuffer();
if(strBinary.substring(0, 3).equals("000")) k=3;
else k=0;
for(int i=k;i<len-2;i+=3){
String string = strBinary.substring(i,i+3);
if(string.equals("000")) stb.append("0");
else if(string.equals("001")) stb.append("1");
else if(string.equals("010")) stb.append("2");
else if(string.equals("011")) stb.append("3");
else if(string.equals("100")) stb.append("4");
else if(string.equals("101")) stb.append("5");
else if(string.equals("110")) stb.append("6");
else if(string.equals("111")) stb.append("7");
/*switch (Integer.valueOf(strBinary.substring(i, i+3))) {
case 000: stb.append("0"); break;
case 001: stb.append("1"); break;
case 010: stb.append("2"); break;
case 011: stb.append("3"); break;
case 100: stb.append("4"); break;
case 101: stb.append("5"); break;
case 110: stb.append("6"); break;
case 111: stb.append("7"); break;
default:
break;
}*/
}
return stb.toString();
}
//16进制转为2进制
private static String toBinary(String strHex) {
int len_str = strHex.length();
StringBuffer stb = new StringBuffer();
for(int i=0;i<len_str;i++){
switch (strHex.charAt(i)) {
case '0': stb.append("0000"); break;
case '1': stb.append("0001"); break;
case '2': stb.append("0010");break;
case '3': stb.append("0011"); break;
case '4': stb.append("0100"); break;
case '5': stb.append("0101"); break;
case '6': stb.append("0110"); break;
case '7': stb.append("0111"); break;
case '8': stb.append("1000"); break;
case '9': stb.append("1001"); break;
case 'A': stb.append("1010"); break;
case 'B': stb.append("1011"); break;
case 'C': stb.append("1100"); break;
case 'D': stb.append("1101"); break;
case 'E': stb.append("1110"); break;
case 'F': stb.append("1111"); break;
default: break;
}
}
return stb.toString();
}
如果范围不超,就可以使用long了
import java.util.Scanner;
//10进制转16
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
long a = in.nextLong();
System.out.print(Long.toHexString(a).toUpperCase());//将字符串小写字符转换为大写
}
}
特殊回文数
123321是一个非常特殊的数,它从左边读和从右边读是一样的。
输入一个正整数n, 编程求所有这样的五位和六位十进制数,满足各位数字之和等于n
解决办法就是暴力法(把所有5位数6位数循环一遍,判断一下就可以)
回文数
1221是一个非常特殊的数,它从左边读和从右边读是一样的,编程求所有这样的四位十进制数。
第一个办法还是和上文一样的暴力法
第二个办法是数字转StringBUilder,倒置然后判断
public class huiwenNum {
public static void main(String args[]){
String a;
for (int i=1000;i<10000;i++){
a=String.valueOf(i); #字符串转数字 Integer.valueOf("12")
#数字转字符串 String.valueOf(12)
StringBuilder b=new StringBuilder(a); #这里要把String转变为StringBuilder,不然不能用下一句的reverse
b.reverse();
String c=new String(b); #这里就是再把StringBuilder转换成String
if (a.equals(c)){ #字符串的对等对比要用equals,==是用来判断数字的
System.out.println(i); #相同的字符串,如果用==,结果也是FALSE
}
}
}
}
特殊的数字
暴力循环
#Math.pow(a,3)得出的就是a的3次方
杨辉三角
用二维数组结题,发现杨辉三角规律为下一行从第二个数开始为上一行的两数相加,即可解题,主要难点,包含比较多的取值范围的控制
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int a[][]=new int[n][n];//记住二维数组的定义
for(int i=0;i<n;i++){
a[i][0]=1;
a[i][i]=1;
if(i>1){
for(int j=1;j<i;j++){//需要自定义的只有中间的
//所以范围在1~i之间
a[i][j]=a[i-1][j-1]+a[i-1][j];
}
}
}
for(int i=0;i<n;i++){
for(int j=0;j<=i;j++){//注意每个取值范围一定要细心
System.out.print(a[i][j]+" ");
}
System.out.println();
}
}
}
查找整数
给出一个包含n个整数的数列,问整数a在数列中的第一次出现是第几个
一个循环就完了,过
数列特征
过
字母图形
利用字母可以组成一些美丽的图形,下面给出了一个例子:
ABCDEFG
BABCDEF
CBABCDE
DCBABCD
EDCBABC
这是一个5行7列的图形,请找出这个图形的规律,并输出一个n行m列的图形。
这个题的思路较多
第一个先用一个字符串来记录第一行的字母,观察可发现上一行第一个字母+1就是本行的第一个字母,然后把上一行n-1的字母接在后面
第二个第i行的第i位后自左向右的字母也是按ABCDEF…展开的(i=1,2…,26),第i行第i位前自右向左也是按ABCDEF…展开的,根据这个规律写
第三个第i行 j列的字母序号(从0开始编号)是i与j差的绝对值
后两种思路代码:https://blog.csdn.net/allyyhh/article/details/88077960
01字串
对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能。它们的前几个是:
00000
00001
00010
00011
00100
请按从小到大的顺序输出这32种01串。
第一个方法暴力:
public static void main(String[] args) {
// TODO Auto-generated method stub
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
for(int a=0;a<2;a++)
{
for(int b=0;b<2;b++)
{
for(int c=0;c<2;c++)
{
System.out.print(i);
System.out.print(j);
System.out.print(a);
System.out.print(b);
System.out.println(c);
}
}
}
}
}
}
第二种方法:利用1到十进制转二进制的方式
public class Main {
public static void main(String[] args){
for(int i=0;i<32;i++){
String result = Integer.toBinaryString(i);
int n = Integer.parseInt(result);
System.out.printf("%05d\n",n);
}
}
}
闰年判断
过
阶乘计算
输入一个正整数n,输出n!的值。
其中n!=123*…*n。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int i,j;
int jw = 0; //进位
int temp; //存放中间结果
int max = 4000; //4000位
int[] a = new int[max];
a[0] = 1;
for(i = 2; i <= n; i ++) {
for(j = 0; j < max; j++) {
temp = a[j] * i + jw;
jw = temp / 10;
a[j] = temp % 10;
}
}
//找出前置0和结果之间的界限
for(i = max-1;i >= 0;i --){
if(a[i] != 0)
break;
}
//倒序输出
for(j = i;j >= 0;j --)
System.out.print(a[j]);
}
}
高精度加法
大数相加,第一种方法直接使用Biginteger https://blog.csdn.net/zhongkelee/article/details/52289163
import java.math.BigDecimal;
import java.util.Scanner;
public class _2高精度加法 {
public static void main(String[] args) {
BigDecimal aBigDecimal ;
BigDecimal bigDecimal;
BigDecimal cBigDecimal;
Scanner scanner = new Scanner(System.in);
aBigDecimal = scanner.nextBigDecimal();
bigDecimal = scanner.nextBigDecimal();
cBigDecimal = aBigDecimal.add(bigDecimal);
System.out.println(cBigDecimal);
}
}
第二种方法老老实实相加走进位像上一个题一样
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String a;
String b;
int[] k=new int[101];//和 数组
a=sc.nextLine();//存被加数
b=sc.nextLine();//存加数
int[] c=new int[100];
int[] d=new int[100];
//倒存被加数并分割到数组中
for(int i=0;i<a.length();i++) {
c[a.length()-1-i]=Integer.parseInt(a.substring(i,i+1));
}
//倒存加数并分割到数组中
for(int i=0;i<b.length();i++) {
d[b.length()-1-i]=Integer.parseInt(b.substring(i,i+1));
}
//两数相加
for(int i=0;i<100;i++) {
k[i]=c[i]+d[i];
}
//相加进位
for(int i=0;i<100;i++) {
if(k[i]>=10) {
k[i+1]+=k[i]/10;
k[i]=k[i]%10;
}
}
int f=0;
for(int i=100;i>=0;i--) {
if(k[i]>0) {
f=i;
break;
}
}
for(int t=f;t>=0;t--) {
System.out.print(k[t]);
}
}
}
Huffuman树
其实这个题感觉主要是如何存储的难点
第一个降序排序,去后两位,相加保存到另一个新建数组
第二个Arrays.sort(a);升序,用Arrays.copyOfRange(T[ ] original,int from,int to)截取生成新的数组,这样循环
import java.util.Arrays;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int n=in.nextInt();
int a[]=new int [n];
for(int i=0;i<n;i++) {
a[i]=in.nextInt();
}
int i=0;
int cost=0,tmp=0;
while(i+1<a.length) {
Arrays.sort(a);
tmp=a[i]+a[i+1];
a[i+1]=tmp;//替换掉第i+1个值
cost=cost+tmp;
//删除第i个元素
a=Arrays.copyOfRange(a, i+1, a.length);
}
System.out.println(cost);
}
}
第三个用ArrayList来做,add,remove
public class Main {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int n=in.nextInt();
ArrayList a=new ArrayList();
for(int i=0;i<n;i++)
a.add(in.nextInt());
while(a.size()>=2) {
f(a);
}
System.out.println(cost);
}
static int cost=0;
static ArrayList f(ArrayList a) {
//Collections是一个工具类,sort是其中的静态方法,是用来对List类型进行排序的
Collections.sort(a);
Object m1=a.get(0);
a.remove(m1);
Object m2=a.get(0);
a.remove(m2);
cost=cost+(int)m1+(int)m2;
a.add((int)m1+(int)m2);
return a;
}
}
2n皇后问题
这是个难点
[
public class Main {
/**
* @param args
*/
static int n;// 有多少组皇后(一白一黑为一组)
static int[] w_place;// w_place[i]: 表示第i个白皇后在第i行第w_place[i]列
static int[] b_place;// b_place[i]: 表示第i个黑皇后在第i行第b_place[i]列
static int[][] arr;
static int result = 0;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sn=new Scanner(System.in);
n=sn.nextInt();
arr=new int[n][n];
w_place = new int[n];
b_place = new int[n];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
arr[i][j]=sn.nextInt();
}
}
backdate(0);// 递归回溯
System.out.println(result);
}
private static void backdate(int i){
if(i> n-1){
result++;
return;
}
int w;//处理第i个皇后
for(w=0;w<n;w++){
if(checkWhite(i, w)){
w_place[i] = w;
arr[i][w]=0;//这是防止回溯的过程中有重复
int b;
for(b=0;b<n;b++){
if(checkBlack(i, b)){
b_place[i] = b;
arr[i][b]=0;
backdate(i+1);//递归到下一行
arr[i][b]=1;//得到一种放置方式后就将当前位置解锁,再向下寻找,不断回溯
}
}
arr[i][w]=1;
}
}
}
private static boolean checkWhite(int i, int j) {
if (arr[i][j] == 0) {
return false;
}
for (int k = 0; k < i; k++) {
if (j == w_place[k] || Math.abs(i - k) == Math.abs(j - w_place[k])) {
return false;
}
}
return true;
}
private static boolean checkBlack(int i, int j) {
if (arr[i][j] == 0) {
return false;
}
for (int k = 0; k < i; k++) {
if (j == b_place[k] || Math.abs(i - k) == Math.abs(j - b_place[k])) {
return false;
}
}
return true;
}
}
报时助手
import java.util.Scanner;
public class Main {
/**
* 不需要用switch进行匹配
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sn=new Scanner(System.in);
int h=sn.nextInt();
int m=sn.nextInt();
int count1,count2,count3;
StringBuilder str=new StringBuilder();
String[] s={"zero","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen","twenty"};
String[] s1={"twenty","thirty","forty","fifty"};
if(h<=20){
str.append(s[h]);
}
else {
count1=h-20;
str.append(s[20]);
str.append(" ");
str.append(s[count1]);
}
str.append(" ");
if(m==0){
str.append("o'clock");
}
else {
if(m<=20){
str.append(s[m]);
}
else {
//匹配十位
count2=m/10-2;
if(m%10==0){
str.append(s1[count2]);
}
else {
count3=m%10;
str.append(s1[count2]);
str.append(" ");
str.append(s[count3]);
}
}
}
System.out.println(str);
}
}
回形取数
我们可以发现两个圈读取的方法是相同的(但下个循环的行数和列数都比前一个循环的少2),所以我们可以采用循环来实现这种取法,循环需要个终止条件,我们不难想到只要取出的个数等于矩阵的总数就让它跳出循环。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc.nextInt();
int[][] a = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
a[i][j] = sc.nextInt();
}
}
int tot = 0, x = -1, y = 0;
while (tot < m * n) {
while (x + 1 < m && a[x + 1][y] != -1) {
System.out.print(a[++x][y]+" ");
a[x][y] = -1;
++tot;
}
while (y + 1 < n && a[x][y + 1] != -1) {
System.out.print(a[x][++y]+" ");
a[x][y] = -1;
++tot;
}
while (x - 1 >= 0 && a[x - 1][y] != -1) {
System.out.print(a[--x][y]+" ");
a[x][y] = -1;
++tot;
}
while (y - 1 >= 0 && a[x][y - 1] != -1) {
System.out.print(a[x][--y]+" ");
a[x][y] = -1;
++tot;
}
}
}
龟兔赛跑预测
累加单位速度算距离
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
//录入数据
int v1 = sc.nextInt();
int v2 = sc.nextInt();
int t = sc.nextInt();
int s = sc.nextInt();
int l = sc.nextInt();
int s1=0,s2=0;//分别表示兔子\乌龟距离起点的距离
int time = 0;
while(s1 < l && s2 < l ){
if(s1 - s2 >= t){//兔子休息
for(int i=0;i<s;i++){
s2 += v2;
time++;
if(s2 == l)//乌龟到达终点
break;
}
}else{//兔子不休息
s1 += v1;
s2 += v2;
time++;
}
}
if(s1 == l && s2 < l)
System.out.println("R");
else if(s1 < l && s2 == l)
System.out.println("T");
else
System.out.println("D");
System.out.println(time);
芯片问题
只要其他的芯片对一个芯片的判断结果是1的个数大于0的个数,
// 就可以判断这个是一个好芯片。为什么呢?因为题目中说了,
// 其中坏的芯片的判断是随即的要不是1要不是0,
// 所以对一个好的芯片(被检测)的判断而言,
// 用坏的去判断(检测方)这个好的,显示1和显示0的概率都是50%,
// 而如果还有一个好的芯片(检测方)也去判断这个好的芯片(被检测),
// 这个结果一定是1,所以这个显示1的总数一定会大于显示0的个数。
FJ的字符串
第一个方法使用递归与动态规划
public class FJString {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt() ;
FJString fj=new FJString();
String v=fj.avc(n);
System.out.println(v);
}
public String avc(int n) {
if (n == 1) return "A";
else {
char c = (char) (n + 64);
return avc(n - 1) + c + avc(n - 1);
}
}
}
Sine之舞
An=sin(1–sin(2+sin(3–sin(4+…sin(n))…)
Sn=(…(A1+n)A2+n-1)A3+…+2)An+1
首先分析一下外层的Sn,需要有大到小递归,也就是n,n-1,n-2……1,以index记录当前递归的位置,那么式子是"("+printfSN(n,index-1)+")"+printfAn(index,1,"")+"+"+(n - index + 1)
对于内层式子,An,需要由小到大递归,也就是1,2,3……n,以index记录递归的位置,以str记录已经拿到的字符串,那么公式就是str+“sin(”+index+operation+printfAn(n, index + 1, str)+")";
public static void main(String[] args) {
Scanner sca = new Scanner(System.in);
int n = sca.nextInt();
System.out.println(printfSN(n, n));
}
private static String printfSN(int n, int index) {
if (index == 1) {
return printfAn(1, 1, "")+"+"+n;
}
return "("+printfSN(n,index-1)+")"+printfAn(index,1,"")+"+"+(n - index + 1);
}
private static String printfAn (int n, int index, String str) {
if (n == index) {
return "sin("+index+")";
}
String operation = "-";
if (index % 2 == 0) {
operation = "+";
}
return str+"sin("+index+operation+printfAn(n, index + 1, str)+")";
}
数的读法
https://blog.csdn.net/qq_27859693/article/details/87548462
完美的代价
对于字符串第一个字符,从字符串的最后一个字符开始匹配,如果找到第一个匹配的位置,将它换到倒数第二的位置,并记录这一次转换所需的次数;如果没有找到匹配的位置,这个字符可能就会是最中间的那个字符,用一个布尔变量记录是否需要将这个可能是中间的字符是否存在。题目的关键就是这个可能是中间的字符需不需要换到中间位置的这种情况,如果将这个字符换到中间,那么以后的字符每次变换都会改变这个中间字符的位置。这个中间字符的左边是已经变换好的,只需要将中间字符的右边作变换就可以了,所以可以将中间字符在最后做变换(下面的代码没有在最后实际作变换,只是统计了它变换需要的次数),最后将右边的字符作回文处理就可以了,如果处理的过程中再次出现可能是中间的字符,那么这种情况就是不可能的了。
————————————————
https://blog.csdn.net/qq_40605470/article/details/79268979
矩形面积交
分别找到2个矩形右下角的坐标中最小的x(minx)和最小的y(miny)—P2的点坐标
在找到2个矩形左上角坐标中最大的x(maxx)和最大的y(maxy)—P3的点坐标
然后就算出了
矩阵乘法
有三种可能性
1.当幂数等于零时,即m=0,结果为对角线上的数都为1,。
2.当幂数等于1时,即m=1,结果为原矩阵。
3.当幂数大于1时,使用矩阵乘法公式进行矩阵相乘。
https://blog.csdn.net/wzt529/article/details/59539832
分解质因数
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
int b = sc.nextInt();
sc.close();
for(int i = a;i <= b;i++) {
factor(i);
}
}
public static void factor(int num) {
int copy = num;
StringBuilder sb = new StringBuilder();
int i = 2;//从小到大枚举因子
while(num != 1) {
if(num % i == 0) {
sb.append(i).append("*");
num /= i;
}else {
i++;
}
}
String res = sb.toString();
System.out.println(copy + "=" + res.substring(0, res.length() - 1)); //去掉最后的 *
}
字符串对比
//先判断长度
if(str1.length()==str2.length()){
if(str1.equals(str2)){
System.out.print(2);
}
else {
//全变成小写然后比较
if(str1.toLowerCase().equals(str2.toLowerCase())){
System.out.print(3);
}
else {
System.out.print(4);
}
}
}
else {
System.out.print(1);
}
}贪心算法模板教程](https://www.cnblogs.com/xiaozhang2014/p/7783795.html)