【算法】【数组与矩阵模块】数组的partition调整

这篇具有很好参考价值的文章主要介绍了【算法】【数组与矩阵模块】数组的partition调整。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

当前所有算法都使用测试用例运行过,但是不保证100%的测试用例,如果存在问题务必联系批评指正~

在此感谢左大神让我对算法有了新的感悟认识!

问题介绍

原问题
给定一个有序数组,但是存在重复,求调整数组,使得数组的右半部分没有重复元素,且升序,数组的左半部分无需保证有序
如:arr = [0,1,1,2,2,2,2,3,3,4,5,6]
结果为:
arr = [0,1,2,3,4,5,6,1,2,2,2,2,3]
进阶问题
给定一个数组arr,arr中仅存在三种类型的元素,如仅存在0,1,2,调整该数组,使得该数组最终变成
00…0011…11…22…22的形式
如:arr = [0,1,1,2,0,1]
结果为:arr = [0,0,1,1,1,2]

解决方案

原问题
1、申请两个游标,i1,和i2,i1作为待交换的index,i2作为遍历的index
2、初始化i1找到arr中第一个满足 arr[i1-1] = arr[i1]的位置
3、从i2 = i1+1开始遍历,如果i2满足 arr[i2] != arr[i1],则交换i2和i1的位置,之后i1++,i2++
进阶问题:
1、申请三个游标,l,r,i,l代表左边第一个arr[l]不为0的地方,r代表右边第一个arr[r]不为2的地方
2、从i = l+1开始遍历,如果arr[i]为1,则i++,如果arr[i]为2,则i位置和r位置交换,r–,如果arr[i]为0,则i位置和l位置交换l++
3、知道i位置和r位置相遇为止

进阶问题

代码编写

java语言版本

原问题:
方法一:


   /**
     * 二轮测试:数组的partition调整
     * @param arr
     */
    public static void partionMoveCp1(int[] arr) {
        if (arr == null || arr.length == 0) {
            return;
        }
        int cur = 1;
        // 从1位置开始找到需要更换的地方
        while (cur < arr.length && arr[cur] != arr[cur-1]) {
            cur++;
        }
        // 从next开始,找与cur不同的
        int next = cur+1;
        while (next < arr.length) {
            if (arr[next] == arr[cur-1]) {
                next++;
            }else {
                // 不相等,交换
                CommonUtils.swap(arr, next, cur);
                next++;
                cur++;
            }
        }
    }

进阶问题

    /**
     * 二轮测试:012数组排序
     * @param arr
     */
    public static void partitionMoveCp2(int[] arr) {
        if (arr == null || arr.length == 0) {
            return;
        }
        int left = 0;
        int right = arr.length-1;
        // left指向第一个不为0的
        while (arr[left] == 0){
            left++;
        }
        // right指向第一个不为2的
        while (arr[right] == 2) {
            right--;
        }
        int cur = left+1;
        // 从left+1开始遍历
        while (cur < right) {
            if (arr[cur] == 2) {
                CommonUtils.swap(arr, cur, right);
                right--;
            }else if (arr[cur] == 0) {
                CommonUtils.swap(arr, cur, left);
                left++;
            }else {
                cur++;
            }
        }
    }



    public static void main(String[] args) {
        int[] ints = {1, 2, 2, 2, 3, 3, 4, 5, 6, 6, 7, 7, 8, 8, 8, 9};
        int[] ints1 = {2, 2, 0, 1, 1, 0, 2};
        partitionMoveCp2(ints1);
        CommonUtils.printArr(ints1);
    }

c语言版本

正在学习中

c++语言版本

正在学习中

思考感悟

这种partition调整考察的就是数组的移动和交换的熟练度,总的来说没有什么特别困难的地方
但是如果这道题提升一个维度,如果4种元素进行排序应该如何玩?
如果是我来做,我可能会将问题转化成3中元素的问题,如何转化?
首先将所有元素遍历一遍,现将要放到最左边或者最右边的元素筛选出来,之后将剩下的元素进行调整,就变成了3中元素的问题。
那么现在如果问题又升级了,如果元素的种类有n中呢?难道我们需要循环n-3次先转化成3个元素的问题吗?
这个时候更多的我可能会考虑提升空间复杂度来降低时间复杂度了,比如hash。。。
如果有空间o(1)的方法希望评论区大神们献计献策~

写在最后

方案和代码仅提供学习和思考使用,切勿随意滥用!如有错误和不合理的地方,务必批评指正~
如果需要git源码可邮件给2260755767@qq.com
再次感谢左大神对我算法的指点迷津!文章来源地址https://www.toymoban.com/news/detail-406296.html

到了这里,关于【算法】【数组与矩阵模块】数组的partition调整的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法训练第二天|977.有序数组的平方、209.长度最小的有序数组、59.螺旋矩阵2

    题目链接:力扣 思路:同样使用双指针的方法,这样就可以只遍历一次原数组。 可以考虑需要按照一个顺序来遍历,那就是从大到小或者从小到大,我选择的是从大到小。 不难看出,原数组将每个数平方后,呈现从两边到中间逐渐减小的规律。 所以使用一个指针指向原数组

    2023年04月22日
    浏览(42)
  • 数据结构与算法—一维数组、二维数组、矩阵、顺序串、链接串的C++代码实现

    1、一维数组:ArrayOneD.h 数组这种数据结构可以看作线性表的推广。数组一般采用顺序存储的方法表示。 这是一个模板类 ArrayOneD 的实现,用于表示一维数组。它包括了 构造函数、拷贝构造函数、析构函数、重载下标运算符、重载赋值运算符、求数组长度、重新设置数组长度

    2024年02月07日
    浏览(45)
  • 【算法挨揍日记】day16——525. 连续数组、1314. 矩阵区域和

    525. 连续数组 给定一个二进制数组  nums  , 找到含有相同数量的  0  和  1  的最长连续子数组,并返回该子数组的长度。 本题的元素只有0和1,根据题目意思,我们可以把题目看成找一段最长的子区间使得区间的0 和1的数量相同,我们可以对其优化将所有的0变成-1,这样这

    2024年02月03日
    浏览(36)
  • 算法训练 Day 2 | 数组:977.有序数组的平方,209.长度最小的子数组,59.螺旋矩阵II

    977. 有序数组的平方 第一想法:暴力破解 看完题解想法:朝着双指针方向想 遇到困难: 用双指针的话,一开始想到两边指针往中间靠,逐个将最大值赋给结果数组。和题解不同的是,循环条件我写了  while (left != right) {...} ,相比于题解的  while (left = right) {...} ,我需要在后

    2023年04月12日
    浏览(37)
  • C++二分查找算法:有序矩阵中的第 k 个最小数组和

    二分查找算法合集 C++二分查找算法:查找和最小的 K 对数字 十分接近m恒等于2 给你一个 m * n 的矩阵 mat,以及一个整数 k ,矩阵中的每一行都以非递减的顺序排列。 你可以从每一行中选出 1 个元素形成一个数组。返回所有可能数组中的第 k 个 最小 数组和。 示例 1: 输入:

    2024年02月05日
    浏览(38)
  • 算法——前缀和之除自身以外数组的乘积、和为K的子数组、和可被K整除的子数组、连续数组、矩阵区域和

    这几道题对于我们前面讲过的一维、二维前缀和进行了运用,包含了面对特殊情况的反操作 目录 4.除自身以外数组的乘积 4.1解析 4.2题解 5.和为K的子数组 5.1解析 5.2题解 6.和可被K整除的子数组 6.1解析 6.2题解 7.连续数组 7.1题解 7.2题解 8.矩阵区域和 8.1解析 8.2题解 4.除自身以外

    2024年04月14日
    浏览(32)
  • 基于FPGA的中值滤波设计————(4)矩阵求取中值算法模块

            前面我们成功找到了3x3的矩阵模板c1~c9,在这一章我们接着需要实现的是midfilter模块,其功能就是通过比较的方式寻找矩阵的中值,用它来代替图像的每一个像素点。如何寻找矩阵的中值呢?分为三步:         第一步: 将矩阵的三行的每一行都按照{大、中、小

    2024年02月11日
    浏览(26)
  • 算法:分区列表86. Partition List

    86. Partition List Given the head of a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x. You should preserve the original relative order of the nodes in each of the two partitions. Example 1: Example 2: Constraints: The number of nodes in the list is in the range [0, 200]. -100 = Node.val =

    2024年02月11日
    浏览(20)
  • 【算法与数据结构】--前言

    欢迎来到《算法与数据结构》专栏!这个专栏将引领您进入计算机科学领域中最重要、最精彩的领域之一:算法与数据结构。不管您是一名初学者,还是已经拥有一定编程经验的开发者,都可以从这里找到有益的知识和实践。 在计算机科学的世界里,算法和数据结构是至关重

    2024年02月07日
    浏览(235)
  • 【优选算法专栏】专题十六:BFS解决最短路问题---前言

    本专栏内容为:算法学习专栏,分为优选算法专栏,贪心算法专栏,动态规划专栏以及递归,搜索与回溯算法专栏四部分。 通过本专栏的深入学习,你可以了解并掌握算法。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:算法从入门到精通 🚚代码仓库:小小unicorn的代码仓库

    2024年04月15日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包