【刷題日記】leetcode-493 翻轉對
一、題目
給定一個陣列 nums ,如果 i < j 且 nums[i] > 2*nums[j] 我們就將 (i, j) 稱作一個重要翻轉對。
你需要返回給定陣列中的重要翻轉對的數量。
示例 1:
輸入: [1,3,2,3,1]
輸出: 2
示例 2:
輸入: [2,4,3,5,1]
輸出: 3
注意:
給定陣列的長度不會超過50000。
輸入陣列中的所有數字都在32位整數的表示範圍內。
二、解題
題目描述的很簡單,拿到題目首先試著用暴力求解,結果果然超時了。想了半天也沒有一個比較清晰的思路,最後去看了題解。
題解基本都先考慮到用歸併排序,在排序的過程中增加滿足條件的資料統計。的確,這是一個很巧妙的想法,利用歸併排序中左陣列都比右陣列小的特性,在歸併過程中增加一次計數的操作就能得到結果,時間複雜度O(nlogn)。詳細的解題思路我就不班門弄斧了,傳送門:「手畫圖解」在歸併排序中加幾行程式碼
在解題之前,我對歸併排序做了個簡單的複習:歸併排序簡單複習。在理解解題思路後,實際編碼中還是有幾個點值得一提:
- leetcode上不要用static進行修飾。由於我開始在本地Idea編碼跑單測,用到了static,貼到LC上測試執行都是正常沒有問題的,但是提交程式碼就執行出錯,輸出了錯誤的結果。
- 對特例入參要仔細考慮清楚,如空陣列、最大整數,直接*2會導致異常等
- 統計翻轉對時,要理解清楚,比較的兩個佇列都是有序的,所以不需要再對佇列下標重置了,見程式碼部分的註釋
// i = 0;
,開始加了這一句導致還是超時。
class Solution {
private int fzd = 0;
public int reversePairs(int[] nums) {
if(nums.length == 0) {
return 0;
}
mergeDividSort(nums);
return fzd;
}
// 歸併排序
private int[] mergeDividSort(int[] nums) {
// 只剩一個元素了
if(nums.length == 1) {
return nums;
} else {
int[] d1 = mergeDividSort(Arrays.copyOfRange(nums, 0, nums.length/2));
int[] d2 = mergeDividSort(Arrays.copyOfRange(nums, nums.length/2, nums.length));
int i = 0;
int j = 0;
while (i < d1.length && j < d2.length) {
// 找到第一個翻轉對
if(d1[i]/2d > d2[j]) {
// i 後面的所有都是翻轉對
fzd += d1.length - i;
// i = 0;
j++;
} else {
i++;
}
}
return mergeSort(d1, d2);
}
}
// 針對兩個有序陣列做合併
private int[] mergeSort(int[] nums1, int[] nums2) {
int[] merged = new int[nums1.length + nums2.length];
int i = 0;
int j = 0;
// 至少清空一個陣列
while(i < nums1.length && j < nums2.length) {
if(nums1[i] < nums2[j]) {
merged[i+j] = nums1[i];
i++;
} else {
merged[i+j] = nums2[j];
j++;
}
}
// 將另一個陣列直接新增到合併後的陣列
if(i == nums1.length && j < nums2.length) {
for (;j < nums2.length; j++) {
merged[i+j] = nums2[j];
}
}
if(j == nums2.length && i < nums1.length) {
for (;i < nums1.length; i++) {
merged[i+j] = nums1[i];
}
}
return merged;
}
}
執行結果:
效率其實還不算高,對比官方題解中歸併排序解法的耗時要稍高一些,主要是我寫的歸併演算法為了方便自己理解,多了一些陣列拷貝相關操作。這裡可以再做優化。
三、小結
這一題還有其他幾種方式的解法,研究後再做更新。
美好的週末從每日一題結束hhh。加油,打工人。
相關文章
- 「翻轉字串」python之leetcode刷題|004字串PythonLeetCode
- 【刷題日記】leetcode-767 重構字串LeetCode字串
- 刷at 藍題日誌
- LeetCode刷題日記 416. 分割等和子集LeetCode
- 刷題記錄
- 記錄刷題日常
- Codeforces 刷題記錄
- CTF刷題記錄
- BUU刷題記錄
- 刷題筆記03筆記
- 刷題筆記02筆記
- LeetCode 刷題筆記LeetCode筆記
- 刷題記錄11
- 刷題記錄27
- 刷題記錄24
- LeetCode刷題記錄LeetCode
- leetcode刷題筆記LeetCode筆記
- leetcode刷題記錄 661~LeetCode
- 【刷題筆記】2024.10.4 test筆記
- cf刷題雜記(2)
- [雜項] 刷題記錄
- leetcode刷題筆記605LeetCode筆記
- noip刷題筆記1筆記
- 想轉行遇到刷題困擾
- 軟考刷題記錄3
- 軟考刷題記錄5
- 劍指offer刷題記錄
- 面試刷題偶有記錄面試
- leetcode刷題筆記(3)(python)LeetCode筆記Python
- 低效程式根源追溯——記一次刷題對效能的不滿
- 演算法小記·字串翻轉演算法字串
- THREEJs 關於對稱軸映象翻轉JS
- 2024年8月刷題記錄
- 2024年10月刷題記錄
- 2024年9月刷題記錄
- 2024年11月刷題記錄
- LeetCode刷題筆記9.2-9.9LeetCode筆記
- leetcode刷題筆記8.5-8.9LeetCode筆記