1. 求未排序数组排序后的相邻元素的最大差值

题目分析: 题目要求的是复杂度为O(n),如果将数组排序,不可能实现O(n)的算法.一种思路是: 利用O(n)的时间复杂度找到数组中的最大值和最小值,然后建立相应数量的桶,遍历原来的数组,将原来数组元素与最小值作差,把元素的数量存入该差值对应下标的桶元素中,保证一个桶只装一个元素.接着求取连续空桶数量最多的数值为多少.

import java.util.*;
public class MaxDivision {
public int findMaxDivision(int[] A, int n) {
int maximum = A[0];
int minimum = A[0];
for(int i =0;i< n;i++){
if(A[i] > maximum){
maximum = A[i];//get the maximum
}
if(A[i] < minimum){
minimum = A[i];//get the minimum
}
}
int[] array = new int[maximum - minimum + 1];//the num of bucket
int len = maximum - minimum + 1;
for(int j = 0;j < A.length; j ++){
array[A[j] - minimum]++;
}///put nums into the bucket
int count = 0;
int max = 0;
for(int k = 0;k < len;k++){
if(array[k] == 0){// if the bucket is empty
count++;
}else{//连续空桶到了尽头
if(max < count){
max = count;//获取当前最大的连续空桶序列长度
}
count = 0;//清空计数值
}
}
return max + 1;
}
}
2. 找到字符串中首先出现三次的字母.

思路: 设置辅助数组长度62, 下标为0~25的元素存储小写字母出现的次数,下标为26~51的元素存储大写字母出现的次数,下标为52~61的元素存储数字出现的次数.不同的类型的元素的下标和元素本身存在一定的换算关系.
- 小写字母的ASCII码为a~z 97~122 存储下标的范围为 character- 97 ~ character -97(此处的character代表区间内的字符元素强制取整的数值,下同)
- 大写字母的ASCII码为A ~ Z 65~ 90存储下标范围为 character - 65 + 26 ~ character - 65 +51
- 数字的ASCII码为0 ~ 9 38~57 存储的下表范围为character - 48 + 52~ character - 48 +61
最后遍历辅助数组如果有数值为三进行相应的转换并返回相应的字符.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main{
public static char get3Appearence(String str){
char[] array = str.toCharArray();
int[] b = new int[62];
for(char c:array){
if(c >='A' && c <= 'Z') ++b[c - 39];
if(c >='a' && c <= 'z') ++b[c - 97];
if(c >='0' && c <= '9') ++b[c + 4];
for(int i = 0;i < b.length;i++){
if(b[i] == 3){
if(i >=0&& i <= 25 ) return (char)(i + 97);
if(i >=26&& i <= 51)return (char)(i + 39);
if(i >=52&& i <=61) return (char)(i - 4);
}
}
}
return (char)0;
}
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine();
System.out.println(get3Appearence(str));
}
}
看到讨论区有一种比较简便的一种方法:
使用HashMap,以字符为key,以出现的次数为value.
实现如下:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.*;
public class Main{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
char[] array = br.readLine().toCharArray();
HashMap<Character,Integer> map = new HashMap<>();
for(int i = 0;i < array.length;i++){
if((array[i] >= 'a'&& array[i] <= 'z')||(array[i] >= 'A'&&array[i] <= 'Z')){
map.put(array[i],map.containsKey(array[i])? map.get(array[i])+1 : 1);
if(map.get(array[i]) == 3){ //这里注意放在if里面判断一下可以避免map中没有key而导致空指针异常
System.out.print(array[i]);break;
}
}
}
br.close();
}
}
这个方法充分利用了HashMap的特性实现较为简洁而且性能比较高.
网友评论