test001

1 题目

/**
 *  (2018吉林大学941)一个长度为 n 的数组由负数、0、正数组成。编写函数,将其重新排序为前段都是负数,后段均为非负数的结构。
 *  要求时间复杂度为 O(n)。
 */

2 题解

2.1 法一

2.1.1 解题思路

​ 设置双指针,通过将负值与头指针交换,正值与尾指针交换,最终可以形成一个左负右正中间零的顺序表。

​ 其中,需要理解的是头尾指针的移动以及遍历顺序表的索引值i如何自增。

​ i从第0个位置开始扫描顺序表。

​ 若正,与尾指针交换,此时i不自增。因为还不能知道交换来的这个数是正是负。

​ 若为0,则i自增。

​ 若负,与头指针交换,此时i可自增。因为前面扫到的正数都抛到后面去了,前面不会出现正数。

​ 可以发现,当头指针向后移动或者尾指针向前移动时,其实就是确定了一个元素的最终位置。

2.1.2 过程
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
程序验证:
在这里插入图片描述
2.1.3 结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.1.4 结果分析

时间复杂度O(n),空间复杂度O(1)

2.1.5 代码

void switch_arr(int arr[],int len){
    int head = 0;
    int rear = len - 1;
    int count = 0;
    int i = 0;
    while (count < len){
        if(arr[i] < 0){
            _swap(arr, i, head);
            head++;
            i++;
            count++;
        }else if(arr[i] == 0){
            i++;
            count++;
        }else if(arr[i] > 0){
            _swap(arr, i, rear);
            rear--;
            count++;
        }
//        cout<<"过程数组:";
//        print_arr(arr,len);
    }
}

2.2 法二

2.2.1 解题思路

牺牲空间换时间,直接开辟另外一个数组填入数值即可。这里也需要左右指针。

2.2.2 过程

比较简单,这里省略了。

2.2.3 结果

在这里插入图片描述
在这里插入图片描述

2.2.4 结果分析

时间复杂度O(n),空间复杂度O(n)

2.2.5 代码

int* switch_arr_2(int arr[],int len){
    int* copy_arr = (int*)malloc(sizeof (int) * len);
    int head = 0;
    int rear = len-1;
    for (int i = 0; i < len; ++i) {
        if(arr[i]<0){
            copy_arr[head++] = arr[i];
        }else if(arr[i]>0){
            copy_arr[rear--] = arr[i];
        }
    }
    for (int i = head; i <= rear; ++i) {
        copy_arr[i] = 0;
    }
    return copy_arr;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值