“前正后负”的算法理解

每日一题中一个编程题目,情景描述:一个长度为n的数组,数组由正数,0,负数组成,编写一个函数,将其重新排序为前段都是负数,0位于中间,后段均为负数的结构。要求时间复杂度为O(n)。

代码如下:

#include<iostream>
using namespace std;

//函数声明
void sort(int array[], int length);
void temp(int &a, int &b);
int main() {
	int array[10] = {1,-5,6,-6,-7,8,-9,3,0,2};
	sort(array,10);
	for (int i = 0; i < 10; i++) {
		printf("%d\t",array[i]);
	}
	printf("\n");
	system("pause");
	return 0;
}

void sort(int array[],int length) {
	int head, rear,count;
	head = 0;
	count = 0;
	rear = length - 1;
	int sum=0;
	for (int i = head; count < length;) {
		if (array[i] > 0) {//如果第i个数大于0,就从最右边开始向左边找小于0的数
			temp(array[i], array[rear]);
			rear--;
			count++;
		}
		else if (array[i] < 0) {//如果第i个数小于0,就与第head数交换,这里主要是对0后面的一些负数处理
			temp(array[i],array[head]);
			i++;
			head++;
			count++;
		}
		else if (array[i] == 0) {//如果第i个数等于0就跳过,0后面可能还有负数
			i++;
			count++;
		}
		sum++;
	}
	printf("时间复杂度为:%d\n",sum);
}

//交换ab
void temp(int &a, int &b) {
	int temp;
	temp = a;
	a = b;
	b = temp;
}

此代码复杂度为O(n),空间复杂度为O(1),此方法比较巧妙,下面是我对此方法的理解:

首先此方法有两个指针:head(头指针),rear(尾指针),head初始化为0,rear初始化为length-1;

①如果数组中第i个数大于0时,就把第i个数与第rear个数交换,temp(array[i],array[rear]),如果从rear处交换来的数字大于0,将会一直交换,直到交换来的数为负数或0时i才向后移动(此方法在做把负数向前面放,把正数往后面放);

②如果数组中第i个数为0时,i向后移动,这时head不移动,head指向的是为0;

③如果数组中第i个数小于0时,把i与head交换,temp(array[i],array[head]),然后i和head都向右移,这个交换主要是在处理当碰到0后交换,在碰到0之前,head一直都是等于i的,

对于count,它是用于控制循环次数的,无论是小于0,大于0,等于0count都要自加,严格控制循环次为n

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值