题一:调整数组顺序,奇数在左,偶数在右
调整数组的顺序使奇数位于偶数前面:输入一个整数数组,调整数组中数字的顺序使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)。
(用快速排序思想)
import java.util.Scanner;
public class LianXi {
public static void quickSort(int []A, int p, int r){
if(p<r){
int q = partition2(A, p, r);
quickSort(A, p, q-1);
quickSort(A, q+1, r);
}
}
public static int partition2(int[]A, int p, int r){
int left = p + 1;
int right = r;
while(left <= right){
while(left <= right && A[left]%2 != 0){
left++;
}
while(left <= right && A[right]%2 == 0){
right--;
}
if(left < right)
swap(A, left, right);
}
swap(A, p, right);
return right;
}
public static void swap(int[] A, int left, int right) {
int temp = A[left];
A[left] = A[right];
A[right] = temp;
}
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();
}
System.out.println("初始数组为:");
for(int i = 0; i<N; i++){
System.out.print(A[i] + " ");
}
System.out.println("\n");
quickSort(A,0,N-1);
System.out.println("排序后数组为:");
for(int j = 0; j<N; j++){
System.out.print(A[j] + " ");
}
}
}
题二:第k小的数
用尽量高的效率求出一个乱序数组中按数值顺序的第k个元素的值。
import java.util.Scanner;
public class LianXi {
public static int selectK(int []A, int p, int r, int k){
int q = partition2(A, p, r); //主元的下标
int qk = q - p + 1; //主元是第几个元素
if(qk == k){
return A[q];
}
else if(qk > k){
return selectK(A, p, q-1, k);
}
else
return selectK(A, q+1, r, k - qk);
}
public static int partition2(int[]A, int p, int r){
int pivot = A[p];
int left = p + 1;
int right = r;
while(left <= right){
while(left <= right && A[left] <= pivot){
left++;
}
while(left <= right && A[right] > pivot){
right--;
}
if(left < right)
swap(A, left, right);
}
swap(A, p, right);
return right;
}
public static void swap(int []A, int left, int right){
int temp = A[left];
A[left] = A[right];
A[right] = A[temp];
}
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();
}
System.out.println("初始数组为:");
for(int i = 0 ; i<N; i++){
System.out.print(A[i] + " ");
}
System.out.println("\n");
System.out.println("请输入k");
int k = in.nextInt();
int t = selectK(A, 0, N, k);
System.out.println("结果为:" + t);
}
}
题三:超过一半的数字
数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字。
(排序后求数组长度一半的下标对应的元素)
import java.util.Arrays;
import java.util.Scanner;
public class LianXi {
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();
}
System.out.println("初始数组为:");
for(int i = 0; i<N; i++){
System.out.print(A[i] + " ");
}
System.out.println("\n");
Arrays.sort(A);
System.out.println("结果为:");
System.out.println(A[A.length / 2]);
}
}
题四:最小可用ID
在非负数组(乱序)中找到最小的可分配ID(从1开始编号)
解法1:排序后,直接遍历找不配对的数
import java.util.Arrays;
import java.util.Scanner;
public class LianXi {
public static int solve1(int []A){
Arrays.sort(A);
int i = 0;
while(i < A.length){
if((i+1) != A[i])
return i+1;
else
i++;
}
return i+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();
}
System.out.println("初始数组为:");
for(int i = 0; i<N; i++){
System.out.print(A[i] + " ");
}
System.out.println("\n");
int res = solve1(A);
System.out.println("结果为: " + res);
}
}
解法2:用辅助数组
import java.util.Arrays;
import java.util.Scanner;
public class LianXi {
public static int solve1(int []A){
Arrays.sort(A);
int n = A.length;
int []helper = new int[n+1];
for(int i = 0; i<n; i++){
if(A[i]<n+1)
helper[A[i]] = 1;
}
for(int i = 1; i<=n; i++){
if(helper[i]==0)
return i;
}
return n + 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();
}
System.out.println("初始数组为:");
for(int i = 0; i<N; i++){
System.out.print(A[i] + " ");
}
System.out.println("\n");
int res = solve1(A);
System.out.println("ID为: " + res);
}
}