劍指Offer面試題:1.找出數組中重複的數字

一、題目

在一個長度爲n的數組裏的所有數字都在0到n-1的範圍內。數組中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出數組中任意一個重複的數字。例如,如果輸入長度爲7的數組{2, 3, 1, 0, 2, 5, 3},那麼對應的輸出是重複的數字2或者3。

二、思路

算法1
將當前位置的數值放到他的位置上去,比如{2,2,3,3,4},將nums[0]的數應該放到nums[2]上,即將該數組放到他在數組中和他角標相等的位置,每次都檢查要交換的位置上的數值是否一樣,如果一樣,則重複,如果不一樣,則交換。

算法2
用hashset的add方法,如果哈希表中沒有這個數據,則返回true並加入,如果有,則返回false
時間複雜度分析:o(n)

三、解決問題

3.1 代碼實現

/**
     * 找到數組中一個重複的數字
     * 返回-1代表無重複的數字或者輸入無效
     * 
     * 將當前位置的數值放到他的位置上去,比如{2,2,3,3,4},
     * 將nums[0]的數應該放到nums[2]上,
     * 即將該數組放到他在數組中和他角標相等的位置,
     * 每次都檢查要交換的位置上的數值是否一樣,
     * 如果一樣,則重複,如果不一樣,則交換。
     */
    public int getDuplicate(int[] arr){
        if (null == arr || arr.length <= 0){
            System.out.println("數組輸入無效!");
            return -1;
        }
        for (int num : arr){
            //在一個長度爲n的數組裏的所有數字都在0到n-1的範圍內
            if (num < 0 || num > arr.length - 1){
                System.out.println("數字大小超出範圍!");
                return -1;
            }
        }
        //時間複雜度 O(N),空間複雜度 O(1)
        for (int i = 0; i < arr.length; i++) {
            while (arr[i] != i){
                // 即將該數組放到他在數組中和他角標相等的位置,
                if (arr[i] == arr[arr[i]]){
                    return arr[i];
                }
                // 交換arr[arr[i]]和arr[i]
                int temp = arr[i];
                arr[i] = arr[temp];
                arr[temp] = temp;
            }
        }
        System.out.println("數組中無重複數字!");
        return -1;
    }

    /**
     * 用hashset的add方法,如果哈希表中沒有這個數據,則返回true並加入,如果有,則返回false
     * @param arr
     * @return
     */
    public int getDuplicate1(int[] arr){
        if (null == arr || arr.length <= 0){
            System.out.println("數組輸入無效!");
            return -1;
        }
        for (int num : arr){
            //在一個長度爲n的數組裏的所有數字都在0到n-1的範圍內
            if (num < 0 || num > arr.length - 1){
                System.out.println("數字大小超出範圍!");
                return -1;
            }
        }
        //時間複雜度 O(N),空間複雜度 O(1)
        Set<Integer> set = new HashSet<>();
        Arrays.sort(arr);
        for (int i = 0; i < arr.length; i++) {
            //  boolean add(E e)  如果 set 中尚未存在指定的元素,則添加此元素(可選操作)。
            if (!set.add(arr[i])){
                return arr[i];
            }
        }
        System.out.println("數組中無重複數字!");
        return -1;
    }

3.2 單元測試

1.數組中帶一個或多個重複數字

2.數組中不包含重複的數字

3.無效輸入測試用例(空數組,數組數字越界等)

package SwordOffer;

import org.junit.Test;

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

/**
 * @author kankan
 * @creater 2019-10-24 8:57
 * 題目:在一個長度爲n的數組裏的所有數字都在0到n-1的範圍內。數組中某些數字是重複的,但不知道有幾個數字重複了,
 * 也不知道每個數字重複了幾次。請找出數組中任意一個重複的數字。例如,如果輸入長度爲7的數組{2, 3, 1, 0, 2, 5, 3},
 * 那麼對應的輸出是重複的數字2或者3。
 *
 *
 *
 */
public class Solution2 {
    /**
     * 找到數組中一個重複的數字
     * 返回-1代表無重複的數字或者輸入無效
     *
     * 將當前位置的數值放到他的位置上去,比如{2,2,3,3,4},
     * 將nums[0]的數應該放到nums[2]上,
     * 即將該數組放到他在數組中和他角標相等的位置,
     * 每次都檢查要交換的位置上的數值是否一樣,
     * 如果一樣,則重複,如果不一樣,則交換。
     */
    public int getDuplicate(int[] arr){
        if (null == arr || arr.length <= 0){
            System.out.println("數組輸入無效!");
            return -1;
        }
        for (int num : arr){
            //在一個長度爲n的數組裏的所有數字都在0到n-1的範圍內
            if (num < 0 || num > arr.length - 1){
                System.out.println("數字大小超出範圍!");
                return -1;
            }
        }
        //時間複雜度 O(N),空間複雜度 O(1)
        for (int i = 0; i < arr.length; i++) {
            while (arr[i] != i){
                // 即將該數組放到他在數組中和他角標相等的位置,
                if (arr[i] == arr[arr[i]]){
                    return arr[i];
                }
                // 交換arr[arr[i]]和arr[i]
                int temp = arr[i];
                arr[i] = arr[temp];
                arr[temp] = temp;
            }
        }
        System.out.println("數組中無重複數字!");
        return -1;
    }

    /**
     * 用hashset的add方法,如果哈希表中沒有這個數據,則返回true並加入,如果有,則返回false
     * @param arr
     * @return
     */
    public int getDuplicate1(int[] arr){
        if (null == arr || arr.length <= 0){
            System.out.println("數組輸入無效!");
            return -1;
        }
        for (int num : arr){
            //在一個長度爲n的數組裏的所有數字都在0到n-1的範圍內
            if (num < 0 || num > arr.length - 1){
                System.out.println("數字大小超出範圍!");
                return -1;
            }
        }
        //時間複雜度 O(N),空間複雜度 O(1)
        Set<Integer> set = new HashSet<>();
        Arrays.sort(arr);
        for (int i = 0; i < arr.length; i++) {
            //  boolean add(E e)  如果 set 中尚未存在指定的元素,則添加此元素(可選操作)。
            if (!set.add(arr[i])){
                return arr[i];
            }
        }
        System.out.println("數組中無重複數字!");
        return -1;
    }
    /**
     *數組帶重複數字
     */
    @Test
    public void test1() {
        System.out.print("test1:");
        int[] a = { 1, 2, 3, 2, 4 };
        int dup = getDuplicate1(a);
        if (dup >= 0)
            System.out.println("重複數字爲:" + dup);
    }
    /**
     *數組爲null
     */
    @Test
    public void test2() {
        System.out.print("test2:");
        int[] a = null;
        int dup = getDuplicate(a);
        if (dup >= 0)
            System.out.println("重複數字爲:" + dup);
    }
    /**
     *數組無重複數字
     */
    @Test
    public void test3() {
        System.out.print("test3:");
        int[] a = { 0, 1, 2, 3 };
        int dup = getDuplicate(a);
        if (dup >= 0)
            System.out.println("重複數字爲:" + dup);
    }

    /**
     *數組數字越界
     */
    @Test
    public void test4() {
        System.out.print("test4:");
        int[] a = { 1, 2, 3, 4 };
        int dup = getDuplicate(a);
        if (dup >= 0)
            System.out.println("重複數字爲:" + dup);
    }

}

努力也是需要學習的,別再讓你的努力,只感動了自己!願你的每一次努力,都能爲自己和別人創造價值。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章