数组中轴

一、问题描述

在一维数组(非有序状态)中找出一个元素pivot,使得其左边的元素均小于等于它,右边的元素均大于等于它,要求线性时间复杂度的算法.

二、算法分析

首先从左往右扫描整个数组,求出非递减序列,可以用布尔数组标记。
然后在从右往左扫描,记录扫描过程中的最小值rightMin,在非递减序列序列中找到小于等于这个rightMin的元素即可。

举例:
int[] ary = {1,0,1,0,1,2,1,3,1,2};
从左往右扫描,对应的非递减布尔标记数组为:
flag = {true,false,true,false,true,true,false,true,false,false}
对应的非递减序列为:
{ary[0],ary[2],ary[4],ary[5],ary[7]}
也即
{1,1,1,2,3}

从右向左扫描
当扫描到j=6时,ary[j]=1<=rightMin=1,但是ary[j]不在非递减序列中,该元素非中轴元素。
当扫描到j=4时,ary[j]=1<=rightMin=1,同时ary[j]在非递减序列中,中轴元素找到。

其核心思想在于:目标元素大于其前序列的最大值,小于其后序列的最小值。

三、算法实现

    /*
     * 并不是给定的任何数组都存在这样的中轴元素,例如数组{1,0,3,2}就不存在这样的中轴元素
     * 如果存在,则返回该元素的下标。
     * 如果不存在,则返回-1
     * */
    public static int getBoundary(int[] ary,int low,int high){
        int leftMax = ary[low],rightMin = ary[high];
        boolean[] flag = new boolean[high-low+1];//布尔数组标记从左往右的非递减元素,为true的下标对应到ary中均为非递减序列
        for (int i = low; i <= high; i++) {
            if (ary[i] >= leftMax) {//非递减
                leftMax = ary[i];
                flag[i] = true;
            }else {
                flag[i] = false;
            }
        }
        for(boolean value:flag){
            System.out.print(value+",");
        }
        for (int j = high; j >= low; j--) {//从右向左扫描
            if (ary[j] <= rightMin) {
                rightMin = ary[j];
                if (flag[j]) {return j;}//在非递减序列中找到最后一个小于等于rightMin的元素。
            }
        }
        return -1;//不存在中轴元素
    }
时间: 2024-10-31 19:58:06

数组中轴的相关文章

8个排序算法

#include <iostream> #include <vector> #include <algorithm> using namespace std; /* 1.插入排序.稳定 (1)原理:逐个处理待排序记录,每个记录与前面已排序子序列进行比较,将其插入子序列中正确位置 (2)复杂度:O(n)->O(n^2),O(n^2) 最佳:升序.时间复杂度为O(n) 最差:降序.时间复杂度为O(n^2) 平均:对于每个元素,前面有一半元素比它大.时间复杂度为O(n^

Java基础知识二次学习--第五章 数组

第五章 数组 时间:2017年4月26日15:11:30~2017年4月26日15:15:54 章节:05章_01节  视频长度:09:30 内容:一维数组的内存分析 心得: Java中数组是引用类型 栈里面存的数组的引用 实际对象在堆内存里面 (C与C++是分配在栈里的) 内存图: 元素为引用数据类型的数组 引用类型的数组如上图 时间:2017年4月26日15:16:22~2017年4月26日15:19:00 章节:05章_02节  视频长度:05:25 内容:数组元素的创建与使用 心得: 首

汇编入门之快速排序和数组遍历

原创文章,转载请注明:汇编入门之快速排序和数组遍历 1.程序内容描述 将两个数组X.Y进行从小到大的快速排序后,将两个数组相同的元素按照从大到小的顺序输出到Z中. 2.程序流程图 3.源代码 DATAS SEGMENT COUNT DW 20 BEGINC DW 0 X DB 4,3,5,7,9,0,3,7,8,9,5,4,5,7,1,6,3,6,1,0 Y DB 5,9,7,3,1,6,3,5,4,0,0,1,3,7,2,5,4,5,3,1 Z DB 6 DUP(?) ENT db ';',0

剑指offer (14) 重组数组使得 奇数在偶数前

题目描述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分 解题分析: 其实就是快速排序的思想. 回想一下快速排序的Partition划分函数,每执行一次划分操作,我们就可以 确定中轴值的最终位置, 也就是 <= 中轴值的所有元素都在 其左边,所有 > 中轴值的元素都在 其右边 我们可以从此获得启发,现在题目要求是 所有奇数在左边,所有偶数在右边, 模拟快速排序的划分操作,我们选取一个 偶数,然后执行划分操作, 执行完

移除数组中第一个负数后的所有负数

scala> val a = ArrayBuffer[Int](1, 2,3, 5, -1, 2, -3, -5) a: scala.collection.mutable.ArrayBuffer[Int]= ArrayBuffer(1, 2, 3, 5, -1, 2, -3 , -5)   scala> :paste // Entering paste mode (ctrl-D tofinish)   var foundFirstNegative = false val keepIndexes

NumPy基础:数组和失量计算

NumPy : Numerical Python,是高性能科学计算和数据分析的基础包. 部分功能: ndarray:一个具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组: 用于对整组数据进行快速运算的标准数学函数(无需编写循环): 用于读写磁盘数据的工具以及用于操作内存映射文件的工具: 线性代数.随机数生成以及傅里叶变换功能: 用于集成C.C++.Fortran等语言编写的代码工具: 大部分数据分析应用关注的功能: 用于

Matlab - 求数组的零值与过零点索引

function zeroindex=pickzero(x)%找出数组的零值及过零点(正负相交处,可能偏离0)m = length(x);x1=x(1:m-1);x2=x(2:m);indz = find(x==0); %zero pointindzer = find(x1.*x2<0); %negative/positiven=length(indzer);for i=1:n if abs(x(indzer(i)))>abs(x(indzer(i)+1)) indzer(i)=indzer(

Java中数组的概念

1.什么是二维数组?有几种表达方式?分别是什么? 答:多维数组即数组的数组,即数组的元素也是数组. 例:int[] [] a = {{1},{1,2},{1,2,3}}; 有三种方式 1).int [] [] a;  2).int [] a1 [];  3).int a2 [] []; *强烈推荐用第1种,不容易混淆a的数据类型: 2.多维数组的创建过程是什么? 答: 例:int [] [] a = new int [2] []; a[0] = {1,2,3}; a[1] = {4,5,6};

ES6之主要知识点(六)数组

引自http://es6.ruanyifeng.com/#docs/array 1.扩展运算符(...) 扩展运算符(spread)是三个点(...).它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列. 该运算符主要用于函数调用. function push(array, ...items) { array.push(...items); } function add(x, y) { return x + y; } var numbers = [4, 38]; add(...n