array专题
581 Shortest Unsorted Continuous Subarray
問題:這道題目感概頗多,作為第一個array的簡單題目就被纏住了。具體內容寫在注釋里面了。
217 Contains Duplicate
問題:這道題目可以看出有效的數字組合就是0,10,11三種組合。當遍歷到某一位是0,下標加1;某一位是1,下標加2.如果到最后只剩下最后一位,并且是0,返回true。
學習:我用遞歸實現的,看了一個方法用循環實現了,代碼簡潔。
代碼
118 Pascal’s Triangle
問題:利用楊輝三角形的性質
1 楊輝三角形以正整數構成,數字左右對稱,每行由1主鍵變大,然后變小,變回1;
2 第n行,數字個數為n;
3 第n行,第k個數字為組合數C(k?1)(n?1)C(n?1)(k?1)
4 除每行最左側與最右側元素外,每個數字等于它的左上方與右上方數字之和。
代碼
695 Max Area of Island
問題:計算小島的最大面積,與 85 最大矩形面積的區別是:島的面積只要連通就行,不一定要形成矩形。體現在深度優先搜索上不同。這道題目的精妙還在計算過就讓grid[i][j] = 0,這樣就不會重復計算了。這是我沒有想到的。
代碼
628 Maximum Product of Three Numbers
問題:題目的輸入是一個整數數組,有正數,有負數。要求輸出這些數組中任意三個數字乘積的最大值。
我的想法:最大乘積或者是三個最大正數的乘積,或者是兩個具有最大絕對值的負數乘以最大的正數。那么我是不是可以按照數字的絕對值從大到小排序。然后找前三個數字相乘就可以。可以嗎?不可以。因為是按照絕對值排序的,所以如果前三個數字恰好都是正數,那也罷了。如果其中一個,原來的數是負數,這個結果就不對了。
學習:思路的第一句是對的。只是處理方法不對。不應該按照數組元素的絕對值排序,這樣之后再也找不到對應的原數字,會出問題。應該看到兩個具有最大絕對值的負數就是整個數組中最小的兩個數。如果能看到這個,就能找到解決方法了。
學習2:最大乘積或者是三個最大正數的成績,或者是兩個具有最大絕對值的負數乘以最大的正數。對這句話可以再理解:找到最大的三個數max1,max2,max3,最小的兩個數min1,min2。這應該一次循環就可以搞定,無需排序。有時候離成功就是那么近,目標設立對了,方法卻錯了。
public int maximumProductV2(int[] nums) {int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE;int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;for (int num : nums) {if (num > max1) {max3 = max2;max2 = max1;max1 = num;}else if(num > max2){max3 = max2;max2 = num;}else if(num > max3){max3 = num;}if (num < min1) {min2 = min1;min1 = num;}else if(num<min2){min2 = num;}}return Math.max(max1 * max2 * max3, min1 * min2 * max1);}代碼
414 Third Maximum Number
問題:題目簡單,只要注意第三大數字=第三大不同的數字,注意去重。而且題目還給了一組最小的數字-2146473648.
public int thirdMax(int[] nums) {int max1 = Integer.MIN_VALUE,max2=Integer.MIN_VALUE,max3=Integer.MIN_VALUE;int cnt = 0;boolean minvalue = true;for(int num:nums){if (num > max1) {max3 = max2;max2 = max1;max1 = num;cnt++;}else if(num > max2 && num!=max1){max3 = max2;max2 = num;cnt++;}else if(num > max3 && num!=max1 && num!=max2){max3 = num;cnt++;}else if(num==Integer.MIN_VALUE && minvalue){cnt++;minvalue = false;}}return cnt<3?max1:max3;}643 Maximum Average Subarray I
問題:要找到長度為k的平均值最大的子數組的平均值。只要找到符合條件的子數組即可。題目可以先用for循環,指定子數組的起始位置、結束位置計算;然后會發現超時,為了減少重復的加和步驟,使用滑動窗口的方式。這種窗口滑動的方式在nlp的算法和深度學習中都有使用。
public double findMaxAverageV3(int[] nums, int k) {int n = nums.length;int sum = 0;for (int i = 0; i < k; i++) {sum += nums[i];}int maxSum = sum;for (int i = k; i < n; i++) {sum += nums[i] - nums[i - k];maxSum = Math.max(maxSum, sum);}return (maxSum+0.0)/k;}448 Find All Numbers Disappeared in an Array
問題:題目簡單。輸入一個數組,數組元素是[1,n],n是數組長度。有些元素可能重復,有些元素可能沒出現。返回沒有出現的元素。要求不用額外的空間,用O(n)時間復雜度完成。
我的思路:先使用一個新數組data,長度為n+1。遍歷入參nums,設置data[nums[i]]=1。最后遍歷data[i]=1就表示i出現過,否則就沒有出現。所以關鍵是標記出出現的元素。可以用數組下標和出現的元素關聯起來。如果沒有新數組data,那就在原數組nums上做修改。修改的方式有很多種,例如設置為0,設置為負數,原數組值+n等等。我自己實現的修改數組值為0,方式不夠漂亮,參考了原數組值+n的方式。
代碼
724 Find Pivot Index
問題:從左向右一次選擇pivot的index 當選擇pivot index 為i的時候leftsum=sum(0,i-1),rightsum=sum(i+1,n-1) ;當選擇pinot index 為(i+1)的時候,leftsum=sum(0,i)=sum(0,i-1)+a[i] rigtsum=sum(i+2,n-1)=sum(i+1,n-1)-a[i+1]。注意:左邊可以是0個元素,右邊也可以是0個元素
學習:更加簡潔版本。leftsum + rightsum + nums[i] = sum,所以leftsum和rightsum只要計算一個就可以。只是沒有想明白為什么這個版本更慢了。(pivotIndexV2)
代碼
總結
- 上一篇: SQL SERVER 2005 数据库置
- 下一篇: ssh开发流程