數組可以說是最簡單的一種數據結構,它佔據一塊連續的內存並按照順序存儲數據。
創建數組時,首先需要指定數組的容量大小,然後根據大小預先分配內存。
數組的空間效率不高。經常會有空閒的區域沒有得到充分利用。
數組的時間效率很高。由於數組中內存是連續的,因此可以根據下標在 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;
}
}