注:题目来源于微信公众号“算法爱好者”,喜欢算法的您值得关注!
问题描述:
现有一个n个整数的序列,你要做的就是交换两个数的位置直到整个序列按照升序排列,那么将这个整数序列排好序,需要交换
多少次?例如,1,2,3,5,4,我们只需要交换一次,即将5和4交换即可。
输入描述:
第一行输入一个正整数n(n≤1000),表示数字序列的元素个数,占一行;接下来一行输入从1到n的n个整数排序,中间用空格隔
开
输出描述:
输出序列升序排列需要的最少交换次数
输入例子:
4
4 3 2 1
输出例子:
6
--------------------------------------------------------------------解题分界线-----------------------------------------------------------------------
这个题一看显然就想到了冒泡排序算法,每第i趟排序后,都会从数组内前n-i个元素中选出最大者,放至靠后的第n-i个位置上。
由于此不变性,我们在每一次循环时,不必遍历整个数组,而是访问前n-i个数组元素就可以。这样虽然减少了程序的执行次数,
但是并没有降低该算法时间复杂度,O(n^2)复杂度的程序在解决数据量大的问题时,并不能算有效的算法。这里只是给出了自
己的思考,你对这个问题有何看法呢,或者对这道面试题是否有其他有效的算法?欢迎在评论区留言。下面附上个人的解题源
码,和调试结果:
#include "stdafx.h"
#include<iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int num;//定义长度
cin>>num;
int *arr=new int(num);//定义一维数组用于存放待排序的数
int count=0;//定义交换次数
for(int k=0;k<num;k++)
cin>>arr[k];
//交换算法
bool flag=false;//是否升序的标志位
int j=0;//控制循环次数
int temp;//存放临时变量,用于交换
while(!flag)
{
flag=true;
for(int i=1;i<num-j;i++)
{
if(arr[i]<arr[i-1])//交换并且修改flag,count加1
{
temp=arr[i];
arr[i]=arr[i-1];
arr[i-1]=temp;
count++;//交换次数加1
flag=false;
}
}
j++;
}
cout<<count;
delete [] arr;
return 0;
}
上面这段程序运行后基本问题不大,但是会弹出一个不太理解的报错框,如下:
点击“继续”就可以了,我觉得这应该是数组的内存分配问题。暂且把它当做一个遗留问题,对系统内部的程序运行机制还不是特别
清楚,待日后解决(求大神赐教啊<0 _0>》)。