1.移動零
題目鏈接:283. 移動零 - 力扣(LeetCode)
我們可以定義一個dest,一個cur,dest表示數組中不為零的數的最后一位,cur用來遍歷數組
class Solution {public void moveZeroes(int[] nums) {for(int cur=0,dest=-1;cur<nums.length;cur++){if(nums[cur]!=0){dest++;int tem=nums[dest];nums[dest]=nums[cur];nums[cur]=tem;}}}
}
?
2.復寫零
題目鏈接:1089. 復寫零 - 力扣(LeetCode)
按正序的方式,判斷cur是否為0,如果不是cur++,dest++,如果為0,dest+=2,并且dest經過的兩位都賦值為0,會導致后面的數被覆蓋,所以我們需要換一種方法。
我們可以先找到最后一個復寫的數
先判斷cur位置的值,來決定dest走一步還是兩步,然后根據dest的位置來判斷是否為最后一位,不是dest最后一位,則cur++,如果dest為最后一位,那么cur現在的位置則是最后一個復寫的數。
但是我們發現這樣我們寫的代碼還是有問題
舉一個例子
此時dest指向的位置已經發生了越界
所以我們需要再加上一個判斷當cur(n-1)的位置為0,則cur--,dest-=2
最后我們只需要逆序進行復寫就可以了
代碼如下:
class Solution {public void duplicateZeros(int[] arr) {int cur=0;int dest=-1;int n=arr.length;while(cur<n){if(arr[cur]!=0){dest+=1;}else{dest+=2;}if(dest >= n - 1){break;}cur++;}if(dest==n){arr[n-1]=0;dest-=2;cur--;}while(cur>=0){if(arr[cur]!=0){arr[dest--]=arr[cur--];}else{arr[dest--]=0;arr[dest--]=0;cur--;}}}
}
?
3.快樂數?
題目鏈接:202. 快樂數 - 力扣(LeetCode)
?
所以我們的算法原理:可以定義一個快指針,一個慢指針,快指針每次走兩步,慢指針每次走一步,直至兩個指針相遇,如果相遇時的數為1,則是快樂數,如果不是1,就不是快樂數。?
代碼如下:
class Solution {public int sum(int n){int sum=0;while(n!=0){int t=n%10;sum+=t*t;n/=10;}return sum;}public boolean isHappy(int n) {int slow=n;int fast=sum(n);while(slow!=fast){slow=sum(slow);fast=sum(sum(fast));}return slow==1;}
}
4.盛最多水的容器?
題目鏈接:11. 盛最多水的容器 - 力扣(LeetCode)
大家看到這個題目一定會想到這道題的暴力解法,套兩層for循環,進行暴力枚舉,但是這種解法會超時。O(n2)
我們就要需要找到其中的規律
比如這種情況:
我們從中取出一小部分進行講解
體積無非就是長? *? 寬
我們通過左右的比較,發現6比3大,我們可以將3的位置往前移動一位。
這樣移動的思想就是,我們如果將6往前移動一位,無非就是三種情況
- 寬度減小,高度不變
- 寬度減小,高度也減小
- 寬度減小,高度不變
無論我們怎么樣移動體積都會減小,所以我們每次將兩邊較小的進行移動。
代碼如下:
class Solution {public int maxArea(int[] height) {int left=0;int right=height.length-1;int result=0;while(left < right){int v=Math.min(height[left],height[right]) * (right-left);result=Math.max(v,result);if(height[left]<height[right]){left++;}else{right--;}}return result;}
}
5.有效三角形的個數?
題目鏈接:611. 有效三角形的個數 - 力扣(LeetCode)
規律
class Solution {public int triangleNumber(int[] nums) {Arrays.sort(nums);int n=nums.length;int total=0;for(int i=n-1;i>=2;i--){int left=0;int right=i-1;while(left<right){if(nums[left] + nums[right]<=nums[i]){left++;}else{total+=right-left;right--;}}}return total; }
}
?
6.和為s的兩個數字?
題目鏈接:LCR 179. 查找總價格為目標值的兩個商品 - 力扣(LeetCode)
class Solution {public int[] twoSum(int[] price, int target) {int n=price.length;int left=0;int right=n-1;while(left<right){if(price[left]+price[right]<target){left++;}else if(price[left]+price[right]>target){right--;}else{return new int[]{price[left],price[right]};}}return new int[]{0};}
}
7.三數之和
題目鏈接:15. 三數之和 - 力扣(LeetCode)?
小優化:
class Solution {public List<List<Integer>> threeSum(int[] nums) {Arrays.sort(nums);List<List<Integer>> ret =new ArrayList<>();int n=nums.length;for(int i=0;i<n;){int left=i+1;int right=n-1;int target=-nums[i];if(nums[i]>0){break;}while(left<right){int sum=nums[left]+nums[right];if(sum>target){right--;}else if(sum<target){left++;}else{ret.add(new ArrayList<Integer>(Arrays.asList(nums[i],nums[left],nums[right])));left++;right--;while(left<right && nums[left]==nums[left-1]){left++;}while(left<right && nums[right]==nums[right+1]){right--;}}}i++;while(i<n-1 && nums[i]==nums[i-1]){i++;}}return ret;}
}
8.四數之和
題目鏈接:?18. 四數之和 - 力扣(LeetCode)
這個題目跟上一個題目基本一致,唯一的差別就是需要外面在套一層循環,整體思路和思想都是一樣的。
注意:要把aim定義為long類型,否則會出現整數溢出的問題
class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> ret=new ArrayList<>();Arrays.sort(nums);int n=nums.length;for(int i=0;i<n;){for(int j=i+1;j<n;){int left=j+1;int right=n-1;long aim=(long)target-nums[i]-nums[j];while(left<right){int sum=nums[left]+nums[right];if(sum>aim){right--;}else if(sum<aim){left++;}else{ret.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));left++;right--;while(left<right && nums[left]==nums[left-1]){left++;}while(left<right && nums[right]==nums[right+1]){right--;}}}j++;while(j<n && nums[j]==nums[j-1]){j++;}}i++;while(i<n && nums[i]==nums[i-1]){i++;}}return ret;}
}
希望能對大家有所幫助!!!?