leetcode面试16刷题记录-部分排序

# 给定一个整数数组,编写一个函数,找出索引m和n,只要将索引区间[m,n]的元素排好序,
# 整个数组就是有序的。注意:n-m尽量最小,也就是说,找出符合条件的最短序列。
# 函数返回值为[m,n],若不存在这样的m和n(例如整个数组是有序的),请返回[-1,-1]。

# 提示:
# 0 <= len(array) <= 1000000
# 我首先想到双指针前后向中间探寻,但是感觉顶不住1M数据量(实际上顶得住)
# 看了看题解,有两轮遍历的
# 有先排序的,再比较的

中间想着能否找到边界直接跳过,踩了坑,我的想法是找到第一个逆序后,向前探查,找到正确的边界:

如[1,3,4,2,5],2、4出现逆序,但是左边界应当在3位置,

但是不能保证中间部分是否有更小的数,比如下列中间序列

[602, 773, 791, 662, 789, 642, 598, 643, 781, 626, 666, 633, 668, 715, 576, 752, 632, 637, 579, 626, 768, 638, 677, 652, 685, 626, 724, 619, 578, 567, 637, 766, 765, 684, 563, 690, 785, 747, 596, 686, 653, 642, 696, 639, 647, 641, 698, 747, 710, 617, 642, 595, 730, 566, 595, 582, 596, 723, 775, 574, 767, 750, 678, 767, 598, 738, 761, 715, 692, 683, 651, 779, 627, 726, 627, 688, 639, 563, 704, 636, 717, 755, 783, 661, 680, 748, 656, 763, 683, 675, 604, 637, 631, 679, 598, 642, 710, 723, 686, 697, 781, 605, 588, 771, 744, 737, 608, 686, 757, 687, 778, 659, 753, 666, 778, 578, 757, 762, 745, 718, 751, 579, 585, 748, 589, 575, 662, 598, 665]
第一个逆序数是791,662,向前探查的结果是773为边界,但是序列后面中间部分有600以下的数,实际探查边界需要依照最小数前移

正确的算法是

对于一个升序序列来说,如果一个数之前,存在比它大的最大值
那么它是一个可选的右边界,我们需要最右边的右边界

从头到尾遍历,不断更新前半段中的最大值,出现逆序则更新右边界

左边界的情况依次类推

换而言之,排序序列应当有此性质,左边界小于中间所有数,右边界大于中间所有数

class Solution:
    # 先排序,然后比较
    def subSort1(self, array: List[int]) -> List[int]:
        if array is None or len(array) < 2:
            return [-1, -1]
        array_1 = array[:]
        array_1.sort()
        if array_1 == array:
            return [-1, - 1]
        for i in range(len(array_1)):
            if array_1[i] != array[i]:
                break
        for j in range(len(array_1) - 1, -1, -1):
            if array_1[j] != array[j]:
                break
        return [i, j]

    # 指针,找到第一个不符合升序的
    # 注意,不能两两比较,而是要比较之前的最值
    # 如[1,3,4,2,5],2、4出现逆序,但是左边界应当在3位置,
    # 想要不进行整个数组的遍历就找到左边界的位置,必须出现逆序后往回找
    # 然而这样也不能解答此题,因为不能保证[l,r]之前是否有更小或更大的数
    # 导致需要拓宽l,r范围
    def subSort(self, array: List[int]) -> List[int]:
        n = len(array)
        if n < 2:
            return [-1, -1]
        l, r = -1, -1
        for i in range(1, n):
            if array[i] < array[i - 1]:
                i0 = i - 1
                # array[i]和 array[i-1]逆序,
                # 需要找到第一个比array[i]小的数
                while i0 >= 0 and array[i0] > array[i]:
                    i0 -= 1
                l = i0 + 1  # 左边界试试后一个数
                break
        if l == -1:
            return [-1, -1]
        for j in range(n - 2, -1, -1):
            if array[j] > array[j + 1]:
                j0 = j + 1
                # array[j]和 array[j + 1]逆序,
                # 需要找到第一个比array[j]大的数
                while j0 < n and array[j0] < array[j]:
                    j0 += 1
                r = j0 - 1  # 右边界是前一个数
                break
        return [l, r]

    # 对于一个升序序列来说,如果一个数之前,存在比它大的最大值
    # 那么它是一个可选的右边界,我们需要最右边的右边界
    # 反之亦然
    def subSort2(self, array: List[int]) -> List[int]:
        n = len(array)
        maxx, minn = -10000000, 10000000
        l, r = -1, -1
        for i in range(n):
            if array[i] < maxx:
                r = i
            else:
                maxx = array[i]
        for i in range(n - 1, -1, -1):
            if array[i] > minn:
                l = i
            else:
                minn = array[i]
        return [l, r]

array = [-796,-795,-791,-790,-790,-789,-787,-783,-782,-781,-778,-778,-771,-769,-766,-764,-763,-762,-760,-757,-754,-751,-750,-750,-738,-735,-735,-732,-731,-729,-728,-725,-723,-721,-719,-713,-713,-711,-707,-704,-702,-700,-699,-697,-697,-696,-696,-696,-696,-695,-695,-690,-690,-689,-688,-688,-688,-687,-685,-685,-683,-682,-680,-679,-679,-677,-677,-675,-674,-673,-665,-664,-662,-660,-659,-655,-654,-654,-654,-652,-652,-651,-650,-650,-644,-643,-641,-641,-639,-639,-639,-638,-637,-637,-637,-628,-625,-621,-615,-611,-608,-605,-601,-600,-594,-594,-592,-589,-587,-582,-582,-581,-579,-579,-578,-577,-574,-570,-569,-568,-566,-566,-565,-560,-555,-552,-547,-540,-538,-535,-535,-535,-534,-534,-530,-529,-528,-526,-522,-520,-520,-519,-512,-509,-508,-506,-505,-505,-502,-502,-497,-490,-489,-488,-481,-481,-474,-474,-473,-472,-471,-470,-468,-467,-466,-465,-463,-460,-457,-456,-455,-451,-451,-450,-450,-449,-448,-448,-447,-446,-443,-440,-438,-438,-435,-434,-433,-424,-422,-416,-415,-412,-411,-410,-408,-407,-407,-406,-404,-402,-395,-391,-390,-390,-385,-383,-379,-379,-379,-373,-372,-367,-361,-360,-353,-344,-343,-343,-339,-338,-336,-333,-332,-332,-332,-330,-329,-328,-326,-324,-319,-317,-317,-311,-311,-305,-305,-302,-302,-302,-301,-298,-298,-296,-293,-292,-290,-290,-289,-285,-284,-282,-280,-277,-277,-273,-272,-271,-266,-264,-262,-254,-251,-250,-248,-246,-244,-241,-240,-239,-237,-237,-235,-233,-229,-220,-220,-216,-214,-212,-211,-209,-207,-205,-199,-199,-198,-196,-196,-195,-194,-194,-193,-192,-191,-185,-185,-185,-182,-182,-179,-172,-170,-167,-162,-161,-160,-156,-155,-155,-153,-152,-150,-148,-147,-141,-140,-139,-138,-134,-134,-130,-127,-127,-124,-122,-116,-115,-112,-104,-101,-100,-99,-98,-96,-96,-92,-92,-87,-84,-84,-79,-77,-75,-75,-73,-71,-70,-67,-66,-65,-61,-61,-60,-59,-59,-59,-58,-58,-55,-54,-51,-50,-43,-42,-40,-37,-35,-33,-32,-29,-28,-27,-26,-23,-21,-20,-18,-14,-11,-6,-4,-3,-1,2,3,7,8,8,9,9,11,19,21,29,29,31,31,32,33,36,38,43,48,48,50,50,51,52,61,62,66,67,69,70,71,78,79,82,82,83,83,84,89,89,92,92,93,93,96,96,98,98,99,99,103,107,109,112,119,120,121,122,123,125,125,130,147,148,151,153,154,154,156,156,158,160,162,164,166,167,170,175,176,177,177,179,182,184,185,188,190,191,192,194,195,198,198,201,203,204,205,207,208,209,210,216,217,218,219,222,227,227,231,231,232,243,245,248,249,257,257,260,261,263,264,267,270,273,275,282,289,298,299,299,299,300,302,303,303,307,308,309,310,310,311,312,313,313,318,318,319,320,321,327,328,328,329,335,336,339,340,342,342,343,344,346,347,349,352,358,360,361,363,363,366,367,369,369,371,371,372,376,378,378,378,379,379,380,383,384,385,392,394,395,395,397,397,397,400,402,405,411,414,415,415,416,421,424,426,427,428,430,431,435,437,438,440,441,447,448,448,449,449,449,451,453,453,458,459,459,461,466,467,470,477,479,482,483,485,485,486,487,494,498,504,504,508,508,510,510,510,511,512,514,517,518,525,526,527,527,527,528,528,529,531,536,537,539,539,540,545,546,546,547,549,549,551,551,553,554,554,558,560,560,602,773,791,662,789,642,598,643,781,626,666,633,668,715,576,752,632,637,579,626,768,638,677,652,685,626,724,619,578,567,637,766,765,684,563,690,785,747,596,686,653,642,696,639,647,641,698,747,710,617,642,595,730,566,595,582,596,723,775,574,767,750,678,767,598,738,761,715,692,683,651,779,627,726,627,688,639,563,704,636,717,755,783,661,680,748,656,763,683,675,604,637,631,679,598,642,710,723,686,697,781,605,588,771,744,737,608,686,757,687,778,659,753,666,778,578,757,762,745,718,751,579,585,748,589,575,662,598,665,629,794,797]
print(array[665: 794])
array_1 = array[:]
array_1.sort()
print(array_1[665: 794])
# array = [1, 3, 5, 7, 9]
solution = Solution()
# array = [1, 3, 9, 7, 5, 6]
# array = [1, 3, 4, 2, 5]
print(solution.subSort(array))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值