日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

【LeetCode笔记】剑指Offer 51. 数组中的逆序对(Java、分治)

發(fā)布時(shí)間:2024/7/23 java 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【LeetCode笔记】剑指Offer 51. 数组中的逆序对(Java、分治) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目描述

  • 多說無益~直接沖代碼吧!

思路 && 代碼

1. 暴力 O(n2n^2n2)

  • 乍一看這題目,很難不直接用暴力法沖一沖(也就雙層循環(huán)的事)
  • 但是不出意料地超時(shí)啦~想一想,O(n2n^2n2)會(huì)超時(shí),那么我們就試著思考怎么降低時(shí)間復(fù)雜度到O(nlogn)吧!(還是不行的話,就再去思考O(n)的方法,循序漸進(jìn)~)
  • 于是,分治的思路就躍然于紙上了~
class Solution {public int reversePairs(int[] nums) {// 暴力int res = 0;int len = nums.length;for(int i = len - 1; i > 0; i--) {for(int j = i - 1; j >= 0; j--) {if(nums[j] > nums[i]) {res++;}}}return res;} }

2. 歸并排序法(分治O(nlogn))

  • 總體框架應(yīng)該是和歸并排序一樣的
  • 從頭思考,如果采用分治的方法進(jìn)行二分,需要有怎樣的考慮?
  • 當(dāng)前遞歸層的結(jié)果,首先應(yīng)該是左半邊內(nèi)部的結(jié)果 + 右半邊內(nèi)部的結(jié)果
  • 然后,應(yīng)該再對左半邊與右半邊的聯(lián)系進(jìn)行處理
  • 為什么要排序?
  • 首先,我們通過二分遞歸的形式,占用了O(logn)的復(fù)雜度
  • 然后,我們需要使用剩下的O(n)復(fù)雜度,完成剩下的步驟
  • 而排序,占用了O(n)復(fù)雜度,同時(shí)實(shí)現(xiàn)了剩下的步驟
  • 左半邊排序、右半邊排序后,并不會(huì)影響左右半邊直接的聯(lián)系,也就是無后效性
  • 合并操作
  • 維護(hù) lowIndex,用于記錄插入左半邊值后,新增的逆序?qū)Α?/li>
  • 插入左半邊值后,增加的逆序?qū)?= 已經(jīng)插入的右邊值個(gè)數(shù)
  • 注意:左半邊當(dāng)前值、右半邊當(dāng)前值相同的情況,選擇插入左半邊當(dāng)前值,這是為了保證正確性。(可以寫個(gè)例子考慮一下就知道原因了~)
class Solution {public int reversePairs(int[] nums) {return mergeSort(nums, 0, nums.length - 1);}public int mergeSort(int[] nums, int left, int right) {if(left >= right) {return 0;}// 1. 二分,先獲取【合并前局部逆序?qū)Α靠倲?shù)int mid = (left + right) / 2;int res = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right);// 2. 合并處理int i = left, j = mid + 1;int[] arr = new int[right - left + 1];// 用于處理相等情況int lowIndex = 0;for(int k = 0; k < arr.length; k++) {if(i > mid){arr[k] = nums[j++];}else if(j > right || nums[i] <= nums[j]) {res += lowIndex;arr[k] = nums[i++];}else if(nums[i] > nums[j]){lowIndex++;arr[k] = nums[j++];}}// 把排序數(shù)組賦予原數(shù)組for(i = left; i <= right; i++) {nums[i] = arr[i - left];}return res;} }

二刷

  • 歸并排序的思想可太能套用了!
class Solution {// 歸并排序public int reversePairs(int[] nums) {return mergeSort(nums, 0, nums.length - 1);}int mergeSort(int[] nums, int left, int right) {if(left >= right) {return 0;}int mid = (left + right) / 2;int res = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right);int[] arr = new int[right - left + 1];int first = left, second = mid + 1;for(int i = 0; i < arr.length; i++) {if(first > mid) {arr[i] = nums[second++];}else if(second > right || nums[first] <= nums[second]) {arr[i] = nums[first++];res += second - mid - 1;}else if(nums[second] < nums[first]) {arr[i] = nums[second++];}}for(int i = 0; i < arr.length; i++) {nums[left + i] = arr[i];}return res;} }

總結(jié)

以上是生活随笔為你收集整理的【LeetCode笔记】剑指Offer 51. 数组中的逆序对(Java、分治)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。