超过一半的数
package 分治法;
public class 超过一半的数 {
public static void main(String[] args) {
int[] arr= {1,5,2,5,3,5,5,4};
int candidate = arr[0];
int nTimes=0;
int countLastNum=0;
for(int i=0;i<arr.length;i++) {
if(arr[i]==arr[arr.length-1]) {
countLastNum++;
}
if(arr[i]!=candidate) {
if(nTimes==0) {
candidate=arr[i];
nTimes=0;
continue;
}else {
nTimes--;
}
}else {
nTimes++;
}
}
if(countLastNum==2/arr.length) {
System.out.println(arr[arr.length-1]);
}else {
System.out.println(candidate);
}
}
}
超过一半以上的数
package 分治法;
public class 超过一半以上的数 {
public static void main(String[] args) {
int[] arr = {5,5,5,5,1,2,3};
int ans = more_half_num(arr);
System.out.println(ans);
}
private static int more_half_num(int[] arr) {
int l=1;
int r=arr.length-1;
int povit=0;
while(l<=r) {
while(l<=r&&arr[l]<=arr[povit])l++;
while(l<=r&&arr[r]>=arr[povit])r--;
if(l<r) {
int temp = arr[l];
arr[l]=arr[r];
arr[r]=temp;
}
}
int temp=arr[r];
arr[r]=arr[povit];
arr[povit]=temp;
return arr[arr.length/2];
}
}
快速排序
package 分治法;
public class 最快速率_乱序数组中查找第k位 {
public static void main(String[] args) {
int[] arr = { 13, 12, 15, 17, 11, 19, 18, 14 };
int k = 3;
int ans = select_K(arr, 0, arr.length - 1, k);
System.out.println(ans);
}
private static int select_K(int[] arr, int l, int r, int k) {
int p = partition(arr, l, r);
int p_K = p - l + 1;
if (p_K == k)
return arr[p];
else if (p_K > k) {
return select_K(arr, l, p - 1, k);
} else {
return select_K(arr, p + 1, r, k - p_K);
}
}
private static int partition(int[] arr, int l, int r) {
int midValueIndex = get_mid_index(arr,l,r);
int temp = arr[l];
arr[l] = arr[midValueIndex];
arr[midValueIndex] = temp;
int p = l + 1;
int q = r;
while (p <= q) {
while (p <= q && arr[p] <= arr[l])
p++;
while (p <= q && arr[q] >= arr[l])
q--;
if (p < q) {
int temp2 = arr[p];
arr[p] = arr[q];
arr[q] = temp2;
}
}
temp = arr[l];
arr[l] = arr[q];
arr[q] = temp;
return q;
}
private static int get_mid_index(int[] arr, int l, int r) {
int midIndex = l + ((r - l) >> 1);
int max = Math.max(arr[l], arr[midIndex]);
max = Math.max(max, arr[r]);
int min = Math.min(arr[l], arr[midIndex]);
min = Math.min(min, arr[r]);
int midValue = arr[l]+arr[r]+arr[midIndex]-min-max;
return midValue==arr[l]?l:midValue==arr[r]?r:midIndex;
}
}
最快速率_乱序数组中查找第k位
package 分治法;
public class 最快速率_乱序数组中查找第k位 {
public static void main(String[] args) {
int[] arr = { 13, 12, 15, 17, 11, 19, 18, 14 };
int k = 3;
int ans = select_K(arr, 0, arr.length - 1, k);
System.out.println(ans);
}
private static int select_K(int[] arr, int l, int r, int k) {
int p = partition(arr, l, r);
int p_K = p - l + 1;
if (p_K == k)
return arr[p];
else if (p_K > k) {
return select_K(arr, l, p - 1, k);
} else {
return select_K(arr, p + 1, r, k - p_K);
}
}
private static int partition(int[] arr, int l, int r) {
int midValueIndex = get_mid_index(arr,l,r);
int temp = arr[l];
arr[l] = arr[midValueIndex];
arr[midValueIndex] = temp;
int p = l + 1;
int q = r;
while (p <= q) {
while (p <= q && arr[p] <= arr[l])
p++;
while (p <= q && arr[q] >= arr[l])
q--;
if (p < q) {
int temp2 = arr[p];
arr[p] = arr[q];
arr[q] = temp2;
}
}
temp = arr[l];
arr[l] = arr[q];
arr[q] = temp;
return q;
}
private static int get_mid_index(int[] arr, int l, int r) {
int midIndex = l + ((r - l) >> 1);
int max = Math.max(arr[l], arr[midIndex]);
max = Math.max(max, arr[r]);
int min = Math.min(arr[l], arr[midIndex]);
min = Math.min(min, arr[r]);
int midValue = arr[l]+arr[r]+arr[midIndex]-min-max;
return midValue==arr[l]?l:midValue==arr[r]?r:midIndex;
}
}