【算法】【Java】寻找数组中任一一个重复的数字

剑指Offer:第三题
在一个长度为n的数组里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,找出数组中所有重复的数字。
解法一:
先排序在寻找
采用快速排序,时间复杂度是O(nlog(n))

package algorithm.test3;

import java.util.Arrays;
import java.util.HashSet;

public class Q1 {
    public static void main(String[] args) {
        int[] test = new int[]{2, 3, 1, 0, 2, 5, 3};
        quickSort(0,test.length - 1,test);
        HashSet<Integer> integers = new HashSet<>();
        System.out.println(Arrays.toString(test));
        for (int i = 0; i < test.length; i++) {
            if (i == 0) {
                continue;
            }
            if (test[i-1] == test[i]) {
                integers.add( test[i]);
            }
        }
        System.out.println(integers);

    }

    public static void quickSort(int start,int end,int[] test) {
        if (start < end) {
            int partion = getIndex(start, end, test);
            quickSort(start, partion, test);
            quickSort(partion + 1, end, test);
        }
    }

    private static int getIndex(int start, int end, int[] test) {
        // 基准数据
        int tmp = test[start];
        while (start < end) {
            // 当队尾的元素大于等于基准数据时,向前挪动high指针
            while (start < end && test[end] >= tmp) {
                end--;
            }
            // 如果队尾元素小于tmp了,需要将其赋值给low
            test[start] = test[end];
            // 当队首元素小于等于tmp时,向前挪动low指针
            while (start < end && test[start] <= tmp) {
                start++;
            }
            // 当队首元素大于tmp时,需要将其赋值给high
            test[end] = test[start];

        }
        // 跳出循环时low和high相等,此时的low或high就是tmp的正确索引位置
        // 由原理部分可以很清楚的知道low位置的值并不是tmp,所以需要将tmp赋值给arr[low]
        test[start] = tmp;
        return start; // 返回tmp的正确位置
    }
}

解法二:
原地算法:
时间复杂度O(n)
空间复杂度O(1)

public class Method3 {
    public static void main(String[] args) {

        int[] test = new int[]{2, 3, 1, 0, 2, 5, 3};
        System.out.println(answer2(test));
    }

    public static HashSet<Integer> answer2(int[] test) {
        HashSet<Integer> integers = new HashSet<>();
        for (int i = 0; i < test.length; i++) {
            if (test[i] != i) {
                while (test[i] != i) {
                    if(test[i] == test[test[i]]){
                        integers.add(test[i]);
                        break;
                    }
                    int temp = test[i];
                    test[i] = test[test[i]];
                    test[temp] = temp;
                }
            }

        }
        return integers;
    }
}
上一篇:Linux实用指令


下一篇:如何在Ubuntu 18.04上安装Memcached