Topic: If the order is a coding rules AAAAOrder2020-0000001, AAAAOrder2020-0000002, the latter figure is self-growth, if the order number to reach AAAAOrder2020-1000000 (one million), the database should have one million data, at this time I delete two random data (physical delete, and does not consider backup and log), may I ask how to find the data encoded deleted? Given problem-solving ideas, the answer is required to run to get within 1 second.
*今天看到群里有人问了一道这样的题目,想了想,给出了自己的答案。两种方法:方法一:比较愚蠢;方法二:二分查找法。觉得麻烦直接看方法二,会好理解很多。*
1. A method (Method silly)
package com.study;
import java.util.ArrayList;
import java.util.Scanner;
public class testnumber {
public static void main(String[] args) {
ArrayList<String> num = new ArrayList<>();
System.out.print("设置总数据量:");
int total = new Scanner(System.in).nextInt();
System.out.println("输入打算删除的两个数x,y");//模拟随机删除两条数据,0<x,y<=total,x!=y
Scanner input = new Scanner(System.in);
int x = input.nextInt();
int y = input.nextInt();
int[] arr = new int[total-2];
for(int i=0;i<(total-2);i++){//此处可以设置成存一百万条数据,用于模拟从数据库过来的
String str = "a-"+(i+1);//类似格式“AAAAOrde-0000001”
num.add(str);
}
if(x > y){
int temp = y;
y = x;
x = temp;
}
//删除指定的两个数
num.remove(x-1);
num.remove(y-2);
long start = System.currentTimeMillis();
for(int i=0;i<(total-2);i++){
arr[i] = Integer.parseInt(num.get(i).replace("a-",""));
}
find(arr,0,0);
long end = System.currentTimeMillis();
System.out.println("消耗时间:"+(end-start)+"毫秒");
}
public static void find(int[] arr,int start,int flag){
if(flag == 1){
for(;start<arr.length;start++){
if(arr[start] - start == 3){
System.out.println("删除的编号:"+(arr[start]-1));
return;
}
}
}else{
for(;start<arr.length;start++){
if(arr[start] - start == 3){
System.out.println("删除的编号:"+ (arr[start]-1)+"和"+(arr[start]-2));
return;
}else if(arr[start] - start == 2){
flag = 1;
System.out.println("删除的编号:"+(arr[start]-1));
find(arr,start+1,flag);
return;//此处一定要有return,不然还会继续执行代码
}
}
}
}
}
operation result:
2. Method Two: binary search
package com.study;
import java.util.ArrayList;
import java.util.Scanner;
public class testnumber {
public static void main(String[] args) {
ArrayList<String> num = new ArrayList<>();
System.out.print("设置总数据量:");
int total = new Scanner(System.in).nextInt();
System.out.println("输入打算删除的两个数x,y");
Scanner input = new Scanner(System.in);
int x = input.nextInt();
int y = input.nextInt();
int[] arr = new int[total - 2];
for (int i = 0; i < total; i++) {//此处可以设置成存一百万条数据,用于模拟从数据库度过来的
String str = "a-" + (i + 1);//类似格式“AAAAOrde-0000001”
num.add(str);
}
if (x > y) {
int temp = y;
y = x;
x = temp;
}
//删除指定的两个数
num.remove(x - 1);
num.remove(y - 2);
long start = System.currentTimeMillis();
for (int i = 0; i < (total - 2); i++) {
arr[i] = Integer.parseInt(num.get(i).replace("a-", ""));
}
int flag =0;//用于标记找到了几个数,当flag=2时,退出循环,已经找到两个数。可以扩展到flag个数,删除flag个整数,然后进行查找
for(int i=1;i<=total && flag!=2;i++){
int res = find3(arr, i, flag);
if(res != -10){
System.out.println("删除的数字为:"+res);
}
}
long end = System.currentTimeMillis();
System.out.println("消耗时间:" + (end - start) + "毫秒");
}
public static int find3(int[] a, int i, int flag) {
int start = 0;
int end = a.length;
while (start <= end) {
int mid = (start + end) / 2;
if (i < a[mid]) {
end = mid - 1;
} else if (i > a[mid]) {
start = mid + 1;
} else {
return -10;//说明这个数存在
}
}
flag++;
return i;
}
}
Method Two obvious better understand and more simple. Here to use a binary search through a reverse thinking. Original binary search is used in an ordered array, search for a value found in the corresponding array subscripts returns; returns -1 if finding. But here we do the opposite: Title means to find the missing two numbers, then the situation just need finding out, modified to return this value is missing, you can find a lack of values we need. Thereby circulating a million times, we are here with the flag as a symbol, when flag == 2, then exit the for loop. Here you can promote it, you are missing x numbers, trying to find out which numbers x, then the corresponding x can be modified to the flag.