Algorithm topic: If the order is a coding rules AAAAOrder2020-0000001, AAAAOrder2020-0000002

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:
Here Insert Picture Description

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;
    }
}

Here Insert Picture Description
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.

Published 33 original articles · won praise 5 · views 20000 +

Guess you like

Origin blog.csdn.net/qq_41623154/article/details/105082605