【例題】數組


數組可以說是最簡單的一種數據結構,它佔據一塊連續的內存並按照順序存儲數據。
創建數組時,首先需要指定數組的容量大小,然後根據大小預先分配內存。

數組的空間效率不高。經常會有空閒的區域沒有得到充分利用。
數組的時間效率很高。由於數組中內存是連續的,因此可以根據下標在 O(1) 時間讀/寫任何元素。(可根據數組時間效率高的優點,用數組來實現簡單的哈希表,這樣的哈希表可以在 O(1) 實現查找)


《劍指offer》- 數組中重複的數字

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


方法一: 先排序
解決這個問題的一個簡單方法是 先把輸入的數組排序。從排序的數組中找出重複的數字是件很容易的事情,只需要從頭到尾掃描排序後的數組即可。

import java.util.*;
public class Solution {
    //返回任意重複的一個,賦值duplication[0]
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        if (numbers == null || length <= 0)
            return false;
        for (int i = 0; i < length; i++)
            if (numbers[i] < 0 || numbers[i] > length-1)
                return false;
                
        Arrays.sort(numbers);   //數組排序
        for (int i = 0; i < length-1; i++){
            if (numbers[i] == numbers[i+1]){
                duplication[0] = numbers[i];
                return true;
            }
        }
        return false;
    }
}

方法二: 哈希表
在這裏插入圖片描述

import java.util.*;
public class Solution {
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        if (numbers == null || length <= 0)
            return false;
        for (int i = 0; i < length; i++)
            if (numbers[i] < 0 || numbers[i] > length-1)
                return false;
                
        HashSet<Integer> hs = new HashSet<>();
        for(int i = 0; i < length; i++) {
            if(!hs.add(numbers[i])) {
                duplication[0] = numbers[i];
                return true;
            }
        }
        return false;
    }
}

方法三: 空間複雜度是 O(1)
在這裏插入圖片描述

public class Solution {
    //返回任意重複的一個,賦值duplication[0]
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        if (numbers == null || length <= 0)
            return false;
        for (int i = 0; i < length; i++){
            if (numbers[i] < 0 || numbers[i] > length-1)
                return false;
        }
        
        for (int i = 0; i < length; i++){
            while (numbers[i] != i){
                if (numbers[i] == numbers[numbers[i]]){
                    duplication[0] = numbers[i];
                    return true;
                }
                // 交換 numbers[i] 和 numbers[numbers[i]]
                int temp = numbers[i];
                numbers[i] = numbers[temp];
                numbers[temp] = temp;
            }
        }
        
        return false;
    }
}

在這裏插入圖片描述


《劍指offer》- 數組中重複的數字(不修改數組)

題目描述
在一個長度爲 n+1 的數組裏的所有數字都在 1 ~ n 的範圍內,所以數組中至少有一個數字是重複的。請找出數組中任意一個重複的數字,但不能修改輸入的數組。
例如,如果輸入長度爲8的數組{2,3,5,4,3,2,6,7},那麼對應的輸出是重複的數字2或者3。

方法一: 複製到輔助數組
在這裏插入圖片描述
方法二: 二分查找
在這裏插入圖片描述
在這裏插入圖片描述

	public int getDuplication(const int numbers[],int length) {
        if (numbers == null || length <= 0)
            return -1;
        for (int i = 0; i < length; i++){
            if (numbers[i] < 1 || numbers[i] > length-1)
                return -1;
        }
        
        int low = 0;
        int high = length-1;
        
        while (low <= high){
            int mid = (low+high)/2;
            int count = countRange(numbers, length, low, mid);
            
            if (low == high){
                if (count > 1)
                    return numbers[low]
                else
                    break;  
            }
            
            if (count > mid-low+1)
                high = mid;
            else
                low = mid+1;
        }
        return -1;
    }
    
    int countRange(const int numbers[],int length,int start, int end){
        int count = 0;
        for (int i = 0; i < length; i++){
            if (numbers[i] >= start && numbers[i] <= end)
                count++;
        }
        return count;
    }

《劍指offer》- 二維數組中的查找

題目描述
在一個二維數組中(每個一維數組的長度相同),每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述
發現如下規律:
首先選取數組中右上角的數字。
如果該數字等於要查找的數字,則查找過程結束
如果該數字大於要查找的數字,則剔除這個數字所在的
如果該數字小於要查找的數字,則剔除這個數字所在的
每次都選取數組查找範圍內的右上角數字 (同樣也可以選取左下角的數字)


以查找數組7爲例來分析查找的過程:
在這裏插入圖片描述

public class Solution {
    public boolean Find(int target, int [][] array) {
        int rows = array.length;
        int columns = array[0].length;

        if (array == null)
            return false;
        
        int row = 0;
        int col = columns - 1;
        while (row <= rows - 1 && col >= 0){
            if (array[row][col] == target)
                return true;
            else if (array[row][col] < target)
                row++;
            else
                col--;
        }
        return false;
    }
}

在這裏插入圖片描述


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