17.6 给定一个整数数组,编写一个函数,找出索引m和n,只要将m和n之间的元素排好序,整个数组就是有序的。注意:n越小越好,也就是说,找出符合条件的最短序列。

解法:

开始解题之前,让我们先确认一下答案会是什么样的。如果要找的是两个索引,这表明数组中间有一段有待排序,其中数组开头和末尾部分是排好序的。

现在,我们借用下面的例子来解决此题:

1,2,4,7,10,11,7,12,6,7,16,18,19

首先映入脑海的想法可能是,直接找出位于开头的最长递增子序列,以及位于末尾的最长递增子序列。

左边:1,2,4,7,10,11

中间:7,12

右边:6,7,16,18,19

很容易就能找出这些子序列,只需从数组最左边和最右边开始,向中间查找递增子序列。一旦发现元素大小顺序不对,那就是找到了递增/递减子序列的两头。

但是,为了解决这个问题,还需要对数组中间部分进行排序,只要将中间部分排好序,数组所有元素便是有序的。具体来说,就是一下判断条件必须为真:

//左边所有元素都要小于中间所有元素

min(middle)>end(left)

//中间所有元素都要小于右边的所有元素

max(middle)<start(right)

或者,换句话说,对于所有元素:

left<middle<right

实际上,上例的这个条件绝对不可能成立。根据定义,中间部分的元素是无序的。而在上面的例子中,left.end>middle.start且middle.end>right.start一定成立。这样一来,只排序中间部分并不能让整个数组有序。

不过,我们还可以缩减左边和右边的子序列,直到先前的条件成立为止。

令min等于min(middle),max等于max(middle).

对左边部分,我们先从这个子序列的末尾开始,并向左移动,直到找到元素索引i使得array[i]<min;找到后只需排序中间部分,就能让数组的那部分有序。

然后,对右边部分进行类似操作。

C++实现代码:

#include<iostream>
using namespace std; int findEndOfLeftSubsequence(int array[],int n)
{
int i;
for(i=;i<n;i++)
{
if(array[i]<array[i-])
return i-;
}
return n-;
} int findEndOfRightSubsequence(int array[],int n)
{
int i;
for(i=n-;i>=;i--)
{
if(array[i]>array[i+])
return i+;
}
return ;
} int shrinkLeft(int array[],int n,int min_index,int start)
{
int comp=array[min_index];
cout<<comp<<endl;
int i;
for(i=start-;i>=;i--)
{
if(comp>=array[i])
return i+;
}
return ;
} int shrinkRight(int array[],int n,int max_index,int start)
{
int comp=array[max_index];
cout<<comp<<endl;
for(int i=start;i<n;i++)
{
if(comp<=array[i])
return i-;
}
return n-;
} void findUnsortedSequence(int array[],int n)
{
int end_left=findEndOfLeftSubsequence(array,n);
cout<<end_left<<endl;
int start_right=findEndOfRightSubsequence(array,n);
cout<<start_right<<endl;
int min_index=end_left+;
if(min_index>=n)
return;
int max_index=start_right-;
for(int i=end_left;i<=start_right;i++)
{
if(array[i]<array[min_index])
min_index=i;
if(array[i]>array[max_index])
max_index=i;
}
cout<<array[min_index]<<" "<<array[max_index]<<endl;
int right_index=shrinkRight(array,n,max_index,start_right);
int left_index=shrinkLeft(array,n,min_index,end_left);
cout<<left_index<<" "<<right_index<<endl;
} int main()
{
int arr[]={,,,,,,,,,,,};
findUnsortedSequence(arr,);
}

careercup-中等难度 17.6的更多相关文章

  1. OC语言实现中等难度通讯录

    实现中等难度通讯录.需求: 1.定义联系⼈人类Contact.实例变量:姓名(拼⾳音,⾸首字⺟母⼤大写).性别.电话号码. 住址.分组名称.年龄.⽅方法:⾃自定义初始化⽅方法(姓名.电话号码).显⽰示 ...

  2. careercup-中等难度 17.12

    17.12 设计一个算法,找出数组中两数之和为指定值的所有整数对. 解答 时间复杂度O(n)的解法 我们可以用一个哈希表或数组或bitmap(后两者要求数组中的整数非负)来保存sum-x的值, 这样我 ...

  3. careercup-中等难度 17.11

    17.11 给定rand5(),实现一个方法rand7().也即,给定一个产生0到4(含)随机数的方法,编写一个产生0到6(含)随机数的方法. 解法: 这个函数要正确实现,则返回0到6之间的值,每个值 ...

  4. careercup-中等难度 17.9

    17.9 设计一个方法,找出任意指定单词在一本书中的出现频率. 解法: 1 单次查询 遍历这本书的每个单词,计算给定单词出现的次数.时间复杂度O(n),我们无法继续优化它,因为书中的每个单次都需要访问 ...

  5. careercup-中等难度 17.8

    17.8 给定一个整数数组(有正数和负数),找出总和最大的连续序列,并返回总和. 解法: 就是求连续子序列的和最大,不过存在一个问题: 假设整个数组都是负数,怎么样才是正确的行为呢?看看这个简单的数组 ...

  6. careercup-中等难度 17.7

    17.7 给定一个整数,打印该整数的英文描述(例如“One Thousand,Two Hundred Thirty Four”). 解法: 举个例子,在转换19 323 984时,我们可以考虑分段处理 ...

  7. careercup-中等难度 17.5

    17.5 写一个函数来模拟游戏. 游戏规则如下: 4个槽,里面放4个球,球的颜色有4种,红(R ),黄(Y),绿(G),蓝(B).比如, 给出一个排列RGGB,表示第一个槽放红色球,第二和第三个槽放绿 ...

  8. careercup-中等难度 17.4

    17.4 编写一个方法,找出两个数字中最大的那一个.不得使用if-else或其他比较运算符. 解法: 我们可以通过一步步的分析来将需要用到的if-else和比较操作符去掉: If a > b, ...

  9. careercup-中等难度 17.3

    17.3 写一个算法计算n的阶乘末尾0的个数? 解答: 首先,算出n的阶乘的结果再去计算末尾有多少个0这种方法是不可取的, 因为n的阶乘是一个非常大的数,分分种就会溢出.我们应当去分析, 是什么使n的 ...

随机推荐

  1. hdu 3033 I love sneakers!

    I love sneakers! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  2. 【转】Windows搭建Eclipse+JDK+SDK的Android

    原文网址:http://blog.csdn.net/sunboy_2050/article/details/6336480 一 相关下载 (1) Java JDK下载: 进入该网页: http://j ...

  3. 声明顺序 (Bootstrap 编码规范)

    相关的属性声明应当归为一组,并按照下面的顺序排列: Positioning Box model Typographic Visual 由于定位(positioning)可以从正常的文档流中移除元素,并 ...

  4. HDU 1405 The Last Practice

    The Last Practice Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  5. 【原创】Linux下使用SecureCRT的方法:破解&编码

    1.下载SecureCRT软件 ubuntu64位:http://download.csdn.net/detail/cobps/7941145 ubuntu32位:http://download.cs ...

  6. .net 禁止远程查看应用程序错误的详细信息,服务器上出现应用程序错误

    打开页面时出现以下错误   "/"应用程序中的服务器错误. 运行时错误 说明: 服务器上出现应用程序错误.此应用程序的当前自定义错误设置禁止远程查看应用程序错误的详细信息(出于安全 ...

  7. python打包成exe(py2exe)

    对比了几个打包工具,发现py2exe更好用一点,一个命令就可以. 1.获取 http://prdownloads.sourceforge.net/py2exe 下载python版本对应的.直接下载然后 ...

  8. Treap 模板 poj1442&hdu4557

    原理可以看hihocoder上面的讲解,很清楚,不多说了. 模板抄lrj训练指南上面的. /** Treap 实现 名次树 功能: 1.找到排名为k的元素 2.值为x的元素的名次 初始化:Node* ...

  9. Java网络编程(TCP协议-练习-上传文本文件)

    客户端: package WebProgramingDemo; import java.io.BufferedReader; public class UploadTextClient { /** * ...

  10. hdu 4607 (树形DP)

    当时比赛的时候我们找出来只要求出树的最长的边的节点数ans,如果要访问点的个数n小于ans距离直接就是n-1 如果大于的话就是(n-ans)*2+ans-1,当时求树的直径难倒我们了,都不会树形dp ...