赞
踩
读完题目后会发现与之前做的某些题变形过来的,解法一样
用 归并排序 分解小问题.
博客指路:
还有一题也是变形,待补
题目指路: 剑指 Offer 51. 数组中的逆序对
归并思路:
解题思路:
比如样例: 给定数组: 2,0,1
第一次组合排序
给定数组: [2,0],1
结果数组: 2(左区间) > 0 (有区间) >> 1,0,0
排序后变: [0,2],1
[正确] 这时 index = 0, 这个结果是加到 index = 0 的元素 2 上的
第二次组合排序
给定数组: 0,[2,1]
结果数组: 2(左区间)> 1(右区间) >> 1,1,0
排序后变: 0,[1,2]
[错误] int[] arr:[1,1,0]
[正确] int[] arr:[2,0,0]这时 index = 1,元素是2,但这个结果应该是加到 index = 0 上的,它加到了 index = 1
因为这个元素 2 本来就是在 index = 0, 只不过是我们需求将它换位了。
AC Code
class Solution { class lan { int val; int position; public lan(int val, int position){ this.val = val; this.position = position; } public String toString(){ return "[ "+ position + ": " + val +"]"; } } int[] arr ; public List<Integer> countSmaller(int[] nums) { List<Integer> list = new ArrayList<>(); if(nums == null || nums.length == 0) return list; int len = nums.length; lan[] ma = new lan[len]; arr = new int[len]; for (int i = 0; i < len; i++) { ma[i] = new lan(nums[i], i); } divde(0, len - 1, ma); for(int i = 0; i < len; i++){ list.add(arr[i]); } // System.out.println(Arrays.toString(arr)); return list; } public void divde(int start, int end, lan[] nums){ if(start >= end) return ; int mid = start + (end - start) / 2; // 分 divde(start, mid, nums); divde(mid + 1, end, nums); // 核心代码 int p1 = start; while(p1 <= mid){ int p2 = mid + 1; while(p2 <= end && nums[p1].val > nums[p2].val){ // System.out.println(nums[p1]); arr[nums[p1].position]++; p2++; } p1++; } // 合并 lan[] temp = new lan[end - start + 1]; int slow = start, fast = mid + 1; int index = 0; while(slow <= mid || fast <= end){ if(slow > mid){ temp[index++] = nums[fast++]; } else if(fast > end){ temp[index++] = nums[slow++]; } else { if(nums[slow].val < nums[fast].val) { temp[index++] = nums[slow++]; } else if(nums[slow].val >= nums[fast].val){ temp[index++] = nums[fast++]; } } } // 覆盖 for(int k = 0; k < index; k++){ nums[start + k] = temp[k]; } } }
leetcode题解: lankerens leetcode题解
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。