
原地快排模板
| |
| |
| |
| |
| var sortArray = function(nums) { |
| |
| const partition=(arr)=>{ |
| |
| let mid=Math.floor(Math.random()*arr.length) |
| let midValue=arr[mid] |
| |
| let left=0 |
| let right=arr.length-1 |
| |
| while(left<=right){ |
| while(arr[left]<midValue){ |
| left++ |
| } |
| |
| while(arr[right]>midValue){ |
| right-- |
| } |
| |
| if(left<=right){ |
| |
| let temp=arr[left] |
| arr[left]=arr[right] |
| arr[right]=temp |
| |
| left++ |
| right-- |
| } |
| } |
| |
| return right |
| } |
| |
| |
| |
| const quickSort=(arr)=>{ |
| |
| if(arr.length<=1) return arr |
| |
| let pivot=partition(arr) |
| |
| let leftArr=arr.slice(0,pivot+1) |
| let rightArr=arr.slice(pivot+1,arr.length) |
| |
| let orderLeft=quickSort(leftArr) |
| let orderRight=quickSort(rightArr) |
| |
| return [...orderLeft,...orderRight] |
| } |
| |
| console.log( quickSort(nums)) |
| |
| |
| |
| }; |
| |
| sortArray([3,9,7,8,5,13,6]) |
计数排序模板
| |
| |
| |
| |
| var sortArray = function(nums) { |
| |
| |
| |
| let arr=[] |
| |
| for(let i=-50000;i<=50000;i++){ |
| arr[i]=0 |
| } |
| |
| for(let i=0;i<nums.length;i++){ |
| arr[nums[i]]++ |
| } |
| |
| let res=[] |
| |
| for(let i=-50000;i<500001;i++){ |
| |
| while(arr[i]>0){ |
| res.push(i) |
| arr[i]-- |
| |
| } |
| } |
| |
| return res |
| |
| }; |
给你两个数组,arr1
和 arr2
,arr2
中的元素各不相同,arr2
中的每个元素都出现在 arr1
中。
对 arr1
中的元素进行排序,使 arr1
中项的相对顺序和 arr2
中的相对顺序相同。未在 arr2
中出现过的元素需要按照升序放在 arr1
的末尾。
示例 1:
| 输入:arr1 = [2,3,1,3,2,4,6,7,9,2,19], arr2 = [2,1,4,3,9,6] |
| 输出:[2,2,2,1,4,3,3,9,6,7,19] |
示例 2:
| 输入:arr1 = [28,6,22,8,44,17], arr2 = [22,28,8,6] |
| 输出:[22,28,8,6,17,44] |
提示:
1 <= arr1.length, arr2.length <= 1000
0 <= arr1[i], arr2[i] <= 1000
arr2
中的元素 arr2[i]
各不相同
arr2
中的每个元素 arr2[i]
都出现在 arr1
中
完整代码
| |
| |
| |
| |
| |
| var relativeSortArray = function(arr1, arr2) { |
| |
| |
| |
| |
| |
| |
| |
| let arr=new Array(1001).fill(0) |
| |
| let res=[] |
| arr1.forEach((item)=>{ |
| arr[item]++ |
| }) |
| |
| arr2.forEach((item)=>{ |
| while(arr[item]>0){ |
| arr[item]-- |
| res.push(item) |
| } |
| }) |
| |
| arr.forEach((item,index)=>{ |
| while(item>0){ |
| item-- |
| res.push(index) |
| } |
| }) |
| |
| return res |
| |
| |
| }; |
以数组 intervals
表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi]
。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
示例 1:
| 输入:intervals = [[1,3],[2,6],[8,10],[15,18]] |
| 输出:[[1,6],[8,10],[15,18]] |
| 解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6]. |
示例 2:
| 输入:intervals = [[1,4],[4,5]] |
| 输出:[[1,5]] |
| 解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。 |
提示:
1 <= intervals.length <= 104
intervals[i].length == 2
0 <= starti <= endi <= 104
解题思路
| 1. 状态空间暴力,区间没有访问过,开始往后连接,连接过的不能用,循环所有没有访问过的空间,当不能在向下连接时,输出结果 |
| |
| 2. 双关键字排序,即区间l1<=l2 r1<=r2 ,排好序后,判断是否可以向后连接,不行就另起一段,行就放入答案 |
| |
| 3. 差分数组 |
状态空间暴力
| |
| |
| |
| |
| var merge = function(intervals) { |
| |
| |
| |
| |
| |
| intervals.sort((a,b)=>{ |
| return a[0]-b[0] |
| }) |
| |
| |
| let res=[] |
| |
| |
| let visited=new Array(intervals.length).fill(false) |
| |
| let mostDist=[] |
| const dfs=(arr)=>{ |
| |
| mostDist=arr |
| |
| for(let i=0;i<intervals.length;i++){ |
| |
| if(visited[i]) continue |
| |
| |
| if(intervals[i][0]>=arr[0]&&intervals[i][0]<=arr[1]){ |
| visited[i]=true |
| |
| let newArr=new Array() |
| newArr[0]=Math.min(intervals[i][0],arr[0]) |
| newArr[1]=Math.max(intervals[i][1],arr[1]) |
| dfs(newArr) |
| |
| |
| if(mostDist[1]<newArr[1]){ |
| mostDist[1]=newArr[1] |
| } |
| break |
| }else{ |
| |
| break |
| } |
| |
| } |
| |
| return mostDist |
| } |
| |
| |
| |
| for(let j=0;j<intervals.length;j++){ |
| if(!visited[j]){ |
| mostDist=[] |
| visited[j]=true |
| res.push(Array.from(dfs(intervals[j]))) |
| } |
| } |
| |
| |
| return res |
| |
| }; |
双关键字排序+判定
| |
| |
| |
| |
| var merge = function(intervals) { |
| |
| |
| |
| |
| |
| intervals.sort((a,b)=>{ |
| return a[0]-b[0] || (a[0]===b[0]&&a[1]-b[1]) |
| }) |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| let left=-1 |
| |
| let far=-1 |
| |
| let res=[] |
| intervals.forEach((item)=>{ |
| let start=item[0] |
| let end=item[1] |
| |
| if(start<=far){ |
| |
| far=Math.max(far,end) |
| }else{ |
| |
| if(far>=0){ |
| res.push([left,far]) |
| } |
| left=start |
| far=end |
| } |
| }) |
| |
| |
| if(far>=0){ |
| res.push([left,far]) |
| } |
| |
| return res |
| |
| }; |
差分数组
| |
| |
| |
| |
| var merge = function(intervals) { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| let m=[] |
| |
| |
| |
| intervals.forEach((item)=>{ |
| m.push([item[0],1]) |
| m.push([item[1]+1,-1]) |
| }) |
| |
| |
| m.sort((a,b)=>{ |
| return a[0]-b[0]||(a[0]===b[0]&&a[1]-b[1]) |
| }) |
| |
| console.log(m) |
| |
| |
| |
| |
| let count=0 |
| |
| let left=-1 |
| let far=-1 |
| let res=[] |
| m.forEach((item)=>{ |
| if(count===0){ |
| left=item[0] |
| } |
| |
| count+=item[1] |
| |
| if(count===0){ |
| far=item[0]-1 |
| res.push([left,far]) |
| } |
| }) |
| |
| return res |
| |
| |
| }; |
给定一个数组 nums
,如果 i < j
且 nums[i] > 2*nums[j]
我们就将 (i, j)
称作一个*重要翻转对*。
你需要返回给定数组中的重要翻转对的数量。
示例 1:
示例 2:
注意:
- 给定数组的长度不会超过
50000
。
- 输入数组中的所有数字都在32位整数的表示范围内。
解题思路
| 1. 暴力,超时 |
| 2. 条件判断,这里满足不等式i<j nums[i]>2*nums[j], 但是下标和值的不等式矛盾,用二分不能兼顾两边 |
| 3. 一般遇到这边的,使用归并排序,减小规模,减低时间复杂度求解 |
| 4. 满足条件的情况,分为左边部分满足的,右边部分满足的,和 |
| 跨左右部分满足的,因为递归的最后面(只存在左右跨部分满足的(关键)) |
| |
| 5. 是否满足,双指针烧苗,i在左边,j在右边,限固定i,看j是否满足 |
| 6. 双指针的优化 nums[i]>2*nums[j] ,是不是下标在i右边的,也满足,因为数组有序 |
完整代码
| |
| |
| |
| |
| var reversePairs = function(nums) { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| let ans=0 |
| |
| const merge=(arr,left,mid,right)=>{ |
| |
| |
| let temp=new Array(right-left+1) |
| |
| let i=left |
| let j=mid+1 |
| |
| |
| for(let k=0;k<temp.length;k++){ |
| |
| if(j>right||arr[i]<=arr[j]&&i<=mid){ |
| temp[k]=arr[i++] |
| }else{ |
| temp[k]=arr[j++] |
| } |
| } |
| |
| for(let k=0;k<temp.length;k++){ |
| arr[left+k]=temp[k] |
| } |
| } |
| |
| |
| |
| const mergeSort=(arr,left,right)=>{ |
| if(left>=right) return |
| let mid=Math.floor((left+right)/2) |
| |
| mergeSort(arr,left,mid) |
| mergeSort(arr,mid+1,right) |
| |
| |
| |
| for(let i=left,j=mid;i<=mid;i++){ |
| while(j<right&&arr[i]>2*arr[j+1]){ |
| j++ |
| } |
| |
| ans+=(j-mid) |
| } |
| |
| merge(arr,left,mid,right) |
| } |
| |
| mergeSort(nums,0,nums.length-1) |
| |
| |
| return ans |
| }; |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!