一、與其餘高級語言不一樣,Java在數組聲明時並不爲數組分配存儲空間,所以,在聲明的[]中不能指出數組的長度html
二、爲數組分配空間的兩種方法:數組初始化和使用new運算符java
三、未分配存儲空間時,數組變量中只是一個值爲null的空引用,要訪問數組元素,必須須要通過初始化、分配存儲空間建立數組後才能訪問數組的元素node
一維數組定義:數組
int[] arr; //注意int[5] arr;錯誤 int arr[]; int[] arr = {1, 2, 3, 4, 5}; int[] arr = new int[5];
二維數組定義:dom
二維數組便是特殊的一維數組,每一個元素是一個一維數組函數
int[] arr[]; //此種方式最好理解
int arr[][];
int[][] arr;
int arr[][] = {{1,2},{3,4},{5,6,7}};
int arr[][] = new int[3][3]
注意:測試
1. 方式一經過右移計算,若是是負數右移時高位會補充0,此時可能會進入死循環spa
如4(100)返回1, 9(1001)返回2code
public class BitCount { //方式一:移位加計數器 注意java中沒有無符號整形 public static int bitCount(int n){ int count = 0; while(n > 0){ if((n & 1) == 1){ count++; } n >>= 1; } return count; }
public static int bitCount1(int n){ int count = 0; unsigned int flag = 1; while(flag){ if(n&flag){ count++; } flag = flag << 1; } return count; }
//方式三:使用n = n & (n-1) public static int bitCount2(int n){ int count = 0; while(n > 0){ n &= n-1; //消除最右邊的1,和第一種方式等價,只是這個的執行次數由數字中的1決定 count++; } return count; }
public static void main(String[] args) { System.out.println("3: "+ bitCount(3)); System.out.println("8: "+ bitCount(8)); System.out.println("11: "+ bitCount(11)); System.out.println("6: "+ bitCount2(6)); System.out.println("7: "+ bitCount2(7)); System.out.println("13: "+ bitCount2(13)); } }
輸出:htm
3: 2 8: 1 11: 3 6: 2 7: 3 13: 3
http://www.cnblogs.com/graphics/archive/2010/06/21/1752421.html 中提供了不少其餘很巧妙的方法
須要考慮數組是否能夠修改
1)若是數組能夠修改, 時間複雜度O(n)
能夠參考快速排序的思路,基於數組的第k個數字來排序,使得比k小的全部數字排在數組的左邊,比k大的數字排在數組的右邊;另外這種方式找出的前k個數不必定是有序的
借用快速排序中partition函數
public static int partition(int[] data, int start, int end){ if(data == null || start < 0 || end >= data.length){ throw new InvalidParameterException(); } Random rand = new Random(); int index = rand.nextInt(end-start+1)+start; swap(data, index, end); int borderPos = start-1; //記錄小於部分和大於部分的分界點,指向最後一個小於的值 for(index = start; index < end; ++index){ if(data[index] < data[end]){ borderPos++; if(borderPos != index){ swap(data, borderPos, index); } } } borderPos++; swap(data, borderPos, end); return borderPos; } public static void swap(int[] data, int pos1, int pos2){ int tmp = data[pos1]; data[pos1] = data[pos2]; data[pos2] = tmp; }
查找最小的前k個數
public static int[] getSmallestNum(int[] numbers, int k){ if(numbers == null || k <= 0 || k > numbers.length){ throw new InvalidParameterException(); } int start = 0, end = numbers.length -1, index = partition(numbers, start, end); while(index != k-1){ if(index > k-1){ end = index - 1; index = partition(numbers, start, end); }else{ start = index + 1; index = partition(numbers, start, end); } } int[] result = new int[k]; for(int i = 0; i < k; i++){ result[i] = numbers[i]; } return result; }
測試:
public static void main(String[] args) { int[] arr = new int[20]; for(int i=0; i<20; i++){ arr[i] = (int) (Math.random()*100); } for(int i=0,len=arr.length; i<len; i++){ System.out.print(arr[i]+" "); } int[] result = getSmallestNum(arr,5); System.out.println(""); for(int i=0,len=result.length; i<len; i++){ System.out.print(result[i]+" "); }
輸出:
91 69 75 29 69 55 80 44 63 19 36 53 62 45 97 52 8 93 34 38 29 19 8 34 36
2) 使用大根堆
使用大根堆存儲最小的k個數,將前k個數讀入堆中,剩下的數據和堆中的最大值比較,小於最大值即替換最大值,若是比最大值大,丟棄該值,,大根堆的插入和刪除時間複雜度爲O(logk),於是總體的時間複雜度爲O(nlogk)
此種方式不用更改數組,而且適合處理海量數據
public static int[] getSmallestNums1(int[] numbers, int k){ //參數檢查 if(numbers == null || k <= 0){ throw new InvalidParameterException(); } //存儲大根堆,初始值爲numbers的前k個數 int[] heap = new int[k]; for(int i = 0; i < k; i++){ heap[i] = numbers[i]; } int rootIndex = k/2 -1; while(rootIndex >= 0){ reheap(heap, rootIndex, k-1); rootIndex--; } for(int i = k, len = numbers.length; i < len; i++){ //若是數值比最大值小,替換最大值 if(numbers[i] < heap[0]){ heap[0] = numbers[i]; reheap(heap, 0, k-1); } } return heap; } //重建大根堆 public static void reheap(int[] heap, int rootIndex, int end){ int node = heap[rootIndex]; int leftIndex = rootIndex*2 +1; boolean done = false; while(!done && leftIndex <= end){ int index = leftIndex; if(leftIndex+1 <= end){ int rightIndex = leftIndex + 1; if(heap[rightIndex] > heap[leftIndex]){ index = rightIndex; } } if(node < heap[index]){ heap[rootIndex] = heap[index]; rootIndex = index; leftIndex = rootIndex*2 + 1; }else{ done = true; } } heap[rootIndex] = node; }
測試:
public static void main(String[] args) { int[] arr = new int[20]; for(int i=0; i<20; i++){ arr[i] = (int) (Math.random()*100); } for(int i=0,len=arr.length; i<len; i++){ System.out.print(arr[i]+" "); } int[] result = getSmallestNums1(arr,5); System.out.println(""); for(int i=0,len=result.length; i<len; i++){ System.out.print(result[i]+" "); } }
輸出:
91 13 44 34 3 57 62 89 57 62 45 1 40 71 76 18 1 28 32 55 18 13 1 1 3