题一:排序数组中找出和的因子
给定已排序数组arr和k,不重复打印arr中所有相加和为k的不降序二元组
如输入arr = {-8,-4,-3,0,2,4,5,8,9,10}, k = 10
输出(0,10)(2,8)
import java.util.ArrayList;
import java.util.Scanner;
public class LianXi {
public static void partition2(int[]arr, int p, int r, int k){
int pivot = k;
int left = p;
int right = r;
while(left != right){
if(arr[left] + arr[right] < pivot){
left++;
}
else if(arr[left] + arr[right] > pivot){
right--;
}
else {
System.out.println("(" + arr[left] + " , " + arr[right] + ")");
left++;
}
}
}
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int N = in.nextInt();
int[] arr = new int[N];
for(int i = 0; i<N; i++){
arr[i] = in.nextInt();
}
System.out.println("初始数组为:");
for(int i = 0; i<N; i++){
System.out.print(arr[i] + " ");
}
System.out.println("\n");
int k = in.nextInt();
System.out.println("符合条件的结果为:");
partition2(arr,0,arr.length-1,k);
}
}
题二:需要排序的子数组
给定一个无序数组arr,求出需要排序的最短数组长度
要求:-O(n)
如输入:arr = {2,3,7,5,4,6},返回4,因为只要{7,5,4,6}需要排序
import java.util.Scanner;
public class LianXi {
public static int findLen(int[] A, int n){
int p1 = -1;
int p2 = -1;
int max = A[0];
int min = A[n-1];
//扩展右端点:更新历史最高,只要右侧出现比历史最高低的,就应该将右边界扩展到此处
for(int i = 0; i < n; i++){
if(A[i] > max){
max = A[i];
}
//只要低于历史最高峰,就要扩展需排序区间的右端点
if(A[i] < max){
p2 = i;
}
}
//找左端点:更新历史最低,只要左侧出现比历史最低高的,就应该将左边界扩展到此处
for(int i = n-1; i >= 0; i--){
if(A[i] < min){
min = A[i];
}
if(A[i] > min){
p1 = i;
}
}
return p2 - p1 + 1;
}
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 len = findLen(A, A.length);
System.out.println("需要排序的长度为:" + len);
}
}
题三:前k个数
求海量数据(正整数)按逆序排列的前k个数(topK),因为数据量太大,不能全部存储在内存中,只能一个一个地从磁盘或者网络上读取数据,请设计一个高效的算法来解决这个问题
第一行:用户输入K,代表要求topK
随后的N(不限制)行,每一行是一个整数代表用户输入的数据
用户输入-1代表输入终止
请输出topK,空格分隔
import java.util.Scanner;
public class LianXi {
static int[] heap;
static int index = 0;
static int k;
public static void main(String[] args){
Scanner in = new Scanner(System.in);
k = in.nextInt();
heap = new int [k];
int x = in.nextInt();
while(x!=-1){
deal(x); //处理x
x = in.nextInt();
}
printRs();
}
private static void printRs(){
for(int i = 0; i<heap.length; i++){
System.out.print(heap[i] + " ");
}
System.out.println("\n");
}
public static void deal(int x){
if(index < k){
heap[index++] = x;
if(index == k){
//堆化
makeMinHeap(heap);
}
}
//x和堆顶进行比较,如果x大于堆顶,x将堆顶挤掉并向下调整
else if(heap[0] < x){
heap[0] = x;
MinHeapFixDown(heap, 0, k);
printRs();
}
}
static void makeMinHeap(int[] A){
int n = A.length;
for(int i = n/2-1; i>=0; i--){
MinHeapFixDown(A, i, n);
}
}
static void MinHeapFixDown(int[] A, int i, int n){
int left = 2 * i + 1;
int right = 2 * i + 2;
if(left > n){
return ;
}
int min = left;
if(right >= n){
min = left;
}
else{
if(A[right] < A[left]){
min = right;
}
}
if(A[i] <= A[min]){
return ;
}
swap(A,i,min);
MinHeapFixDown(A, min, n);
}
private static void swap(int[] A, int i, int min) {
int temp = A[i];
A[i] = A[min];
A[min] = temp;
}
}
题四:所有员工年龄排序
公司现在要对几万员工的年龄进行排序,因为公司员工的人数非常多,所以要求排序算法的效率要非常高,你能写出这样的程序吗
输入:输入可能包含多个测试样例,对于每个测试案例,
- 输入的第一行为一个整数n(1<=n<1000000): 代表公司内员工的人数
- 输入的第二行包括n个整数:代表公司内每个员工的年龄。其中,员工年龄age的取值范围为(1<=age<=99)。
输出:对应每个测试案例,
- 请输出排序后的n个员工的年龄,每个年龄后面有一个空格。
import java.util.Scanner;
public class LianXi {
public static void countSort(int[] A){
int max = Integer.MIN_VALUE;
for(int num : A){
max = Math.max(max, num);
}
int[] helper = new int[max+1];
for(int num : A){
helper[num]++;
}
int[] result = new int[A.length];
int index = 0;
for(int i = 0; i<helper.length; i++){
while(helper[i]>0){
result[index++] = i;
helper[i]--;
}
}
for(int i = 0; i<result.length; i++){
System.out.print(result[i] + " ");
}
}
public static void main(String[] args){
Scanner in = new Scanner(System.in);
System.out.println("输入员工人数:");
int N = in.nextInt();
int[] A = new int[N];
System.out.println("输入员工年龄:");
for(int i = 0; i<N; i++){
A[i] = in.nextInt();
}
countSort(A);
}
}
题五:数组能排成的最小数
输入一个正整数数组,把数组里所有整数拼接起来排成一个数,打印出能拼接出的所有数字中最小的一个。
例如输入数组{3,32,321},则打印出这3个数字能排成的最小数字为:321323
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int N = in.nextInt();
Integer[] arr = new Integer[N];
for(int i = 0; i<N; i++){
arr[i] = in.nextInt();
}
int res = f(arr);
System.out.print(res);
}
public static int f(Integer[] arr){
Arrays.sort(arr, new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2) {
String s1 = o1 + "" + o2;
String s2 = o2 + "" + o1;
return s1.compareTo(s2);
}
});
StringBuilder sb = new StringBuilder();
for(int i = 0; i < arr.length; i++){
sb.append(arr[i]);
}
return Integer.parseInt(sb.toString());
}
}
题六:数组的包含
输入两个字符创str1和str2,请判断str1中的所有字符是否都存在于str2中
解法1:
import java.util.Scanner;
public class LianXi {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
String s1 = in.next();
String s2 = in.next();
boolean res = check(s1,s2);
if(res == false)
System.out.println("否");
else
System.out.println("是");
}
public static boolean check(String s1, String s2){
for(int i = 0; i<s1.length(); i++){
char a = s1.charAt(i);
if(s2.indexOf(a) == -1)
return false;
}
return true;
}
}
解法2:
import java.util.Arrays;
import java.util.Scanner;
public class LianXi {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
String s1 = in.next();
String s2 = in.next();
boolean res = check(s1,s2);
if(res == false)
System.out.println("否");
else
System.out.println("是");
}
public static boolean check(String s1,String s2){
char[] s2_arr = s2.toCharArray();
Arrays.sort(s2_arr);
for(int i = 0; i<s1.length(); i++){
char a = s1.charAt(i);
int index = Arrays.binarySearch(s2_arr, a);
if(index<0){
return false;
}
}
return true;
}
}