【刷題日記】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字串
- 刷題筆記02筆記
- 刷題筆記03筆記
- LeetCode刷題日記 416. 分割等和子集LeetCode
- 面試刷題偶有記錄面試
- noip刷題筆記1筆記
- LeetCode 刷題筆記LeetCode筆記
- leetcode刷題筆記LeetCode筆記
- LeetCode刷題記錄LeetCode
- 低效程式根源追溯——記一次刷題對效能的不滿
- 刷題記錄(C語言)01C語言
- leetcode刷題筆記605LeetCode筆記
- ctfshow刷題記錄-cry方向-1
- ctfshow刷題記錄-社工篇-1
- 7月18日刷題記錄 二分答案跳石頭遊戲Getting遊戲
- 對日軟體外包專案問題探討(轉)
- (刷題筆記)軟考中級資料庫 上午題筆記資料庫
- 劍指Offer系列刷題筆記彙總筆記
- leetcode刷題筆記(3)(python)LeetCode筆記Python
- LeetCode刷題記錄——day1LeetCode
- LeetCode刷題記錄——day2LeetCode
- LeetCode刷題記錄——day3LeetCode
- LeetCode刷題記錄——day4LeetCode
- LeetCode刷題記錄——day5LeetCode
- ✏️ JavaScript版 | 10大專題 | 劍指offer刷題筆記 ✏️JavaScript筆記
- LeetCode刷題記錄與題解(C++版本)LeetCodeC++
- 演算法小記·字串翻轉演算法字串
- [翻譯] 除錯 Rxjs(二):日誌記錄除錯JS
- LeetCode-劍指Offer刷題記錄LeetCode
- LeetCode刷題記13-27. 移除元素LeetCode
- 力扣刷題Python筆記:括號生成力扣Python筆記
- 程式設計師如何玩轉力扣刷題?程式設計師力扣
- THREEJs 關於對稱軸映象翻轉JS
- 刷題學習
- 每日刷題 3.17
- LeetCode 刷題日記 19. 刪除連結串列的倒數第N個節點LeetCode
- 主題搗鼓日記