首页 > 其他分享 >493. 翻转对

493. 翻转对

时间:2024-03-31 22:31:26浏览次数:18  
标签:arr nums int 数组 493 指针 翻转

Problem: 493. 翻转对

文章目录

思路

这个问题可以使用归并排序的思想来解决。在归并排序的过程中,我们可以统计翻转对的数量。具体来说,对于数组的任意两个子数组,如果左边的子数组的最大值大于右边子数组的最小值的两倍,那么左边子数组中所有大于右边子数组最小值的两倍的元素都可以与右边子数组形成翻转对。

解题方法

我们使用递归的方式,将数组分为左右两部分,然后分别对左右两部分进行排序和统计翻转对的数量。在合并两个已排序的子数组以统计翻转对的数量时,我们可以使用双指针的方法,左指针指向左子数组的开始,右指针指向右子数组的开始,如果左指针指向的元素大于右指针指向的元素的两倍,那么左指针右边的所有元素都可以与右指针形成翻转对,然后右指针向右移动一位,否则,左指针向右移动一位。这样,我们就可以在合并的过程中统计翻转对的数量。

复杂度

时间复杂度:

O ( n log ⁡ n ) O(n \log n) O(nlogn),其中 n 是数组的长度。我们需要对数组进行归并排序,时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn)。

空间复杂度:

O ( n ) O(n) O(n),我们需要额外的空间来存储归并过程中的临时数组。

Code

class Solution {
    public static int MAXN = 50001;
    public static int[] help = new int[MAXN];

    public static int reversePairs(int[] nums) {
        return counts(nums, 0, nums.length - 1);
    }

    private static int counts(int[] nums, int l, int r) {
        if (l == r) {
            return 0;
        }
        int m = (l + r) / 2;
        return counts(nums, l, m) + counts(nums,m + 1, r) + merge(nums, l, m, r);
    }

    private static int merge(int[] arr, int l, int m, int r) {
        int ans = 0;
        for(int i = l, j = m + 1; i <= m; i++) {
            while(j <= r && arr[i] > 2 * (long)arr[j]) {
                j++;
            }
            ans += j - m - 1;
        }
        // 正常merge
        int i = l;
        int a = l;
        int b = m + 1;
        while (a <= m && b <= r) {
            help[i++] = arr[a] <= arr[b] ? arr[a++] : arr[b++];
        }
        while (a <= m) {
            help[i++] = arr[a++];
        }
        while (b <= r) {
            help[i++] = arr[b++];
        }

        for(i = l; i <= r; i++) {
            arr[i] = help[i]; 
        }
        return ans;

    }
}

标签:arr,nums,int,数组,493,指针,翻转
From: https://blog.csdn.net/m0_73939789/article/details/136305821

相关文章

  • 08天【代码随想录算法训练营34期】第四章 字符串part01(● 344.反转字符串 ● 541. 反
    **344.反转字符串**classSolution:defreverseString(self,s:List[str])->None:left=0right=len(s)-1whileleft<right:temp=s[left]s[left]=s[right]s[right]=temp......
  • Leetcode 翻转二叉树
    Day11第三题目前ac最快的一道题/***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*TreeNoderight;*TreeNode(){}*TreeNode(intval){this.val=val;}*TreeNode(intval,TreeNo......
  • P9493 「SFCOI-3」进行一个列的排
    P9493「SFCOI-3」进行一个列的排性质+dp对于题目的限制,我们可以先弱化条件,把\(L_i\)的限制先去掉,转化为序列中至少存在一个\(\rmmex=(0∼i)\)的区间。这时候有结论:序列一定是下凸的,即对于每一个\(i\),满足\(0∼i\)都为一个连续段。这里直接引用irris的证明。有了......
  • 字符串翻转(C++)
    示例:        翻转前:tobeornottobe        翻转后:otebrotonoteb基本思路:        利用strtok字符串切割函数拿到每一部分,存储到一个字符串数组中,再将每一个字符串数组倒置。最后顺序输出。程序代码:#include<iostrem>#include<string>#......
  • 蓝桥杯-翻转
    """题目来源:https://www.lanqiao.cn/problems/3520/learning/?page=1&first_category_id=1&name=%E7%BF%BB%E8%BD%AC"""importosimportsysimportcopy#请在此输入您的代码n=int(input())#n组测评数据data=[[]foriinrange(n)]for......
  • revit二开中文字注释族导出cad后出现翻转的问题
    在revit中存在该一个导出cad的BUG即:revit中的文字注释族中的文字是可以有“可读”选项的,而CAD中是没有该选项的,所以会出现revit导出cad后文字翻转的情况 解决方案跟revit导出cad的机制有关,revit针对自定义族导出到cad中是这样一个机制:同一个形状只导出一个块。解决方案:将文......
  • 如何实现照片镜像翻转(即垂直旋转)?图像翻转怎么弄?图片垂直翻转轻松解决
    一、图片镜像旋转的原理图片镜像旋转,顾名思义,就是将图片进行镜像翻转或旋转。在图像处理中,这通常是通过矩阵变换来实现的。通过构建一个变换矩阵,将图片的每个像素点映射到新的位置,从而实现镜像旋转的效果。这种变换过程遵循线性代数的原理,确保了图像在变换过程中的连续性和稳......
  • 代码随想录算法训练营第十五天| 226. 翻转二叉树 101. 对称二叉树
    226.翻转二叉树https://leetcode.cn/problems/invert-binary-tree/description/publicTreeNodeinvertTree(TreeNoderoot){invert(root);returnroot;}publicvoidinvert(TreeNodenode){if(node==null)return;TreeNod......
  • leedcode-翻转二叉树
    自己写的:classSolution:definvertTree(self,root:Optional[TreeNode])->Optional[TreeNode]:#创建一个新的TreeNode以存储反转后的树newroot=TreeNode()#如果输入的根节点为空,则返回空ifnotroot:......
  • lc493 统计重要翻转对的数目
    给定一个数组nums[n],如果i<j并且nums[i]>2*nums[j],则称(i,j)是一个重要翻转对。求nums[n]中重要翻转对的数量。1<=n<=5e4;nums[i]在int范围内直接套平衡树模板即可。template<typenameTYPE>structTreap{structNode{TYPEdata,sum;intrnd,siz......