4. 移动到末尾(蓝桥云课)
题目描述
给定一个数组,实现一个算法将数组中的所有 0 移动到末尾,但不可改变非 0 数字的相对位置。介绍如下:
- 例如数组为 [0, 1, 0, 3, 12],将所有 0 移动到末尾的结果为 [1, 3, 12, 0, 0]。
输入描述
第一行输入一个数字 N (1<N<1000)N (1<N<1000),为数组的长度。
第二行输入数组的元素 AiAi,0<Ai<10000<Ai<1000。
输出描述
输出一行,为移动后数组。
输入输出样例
示例
输入
5
0 1 0 3 12
输出
1 3 12 0 0
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
方法一(推荐):用一种双指针的思维去从头开始填充数组
#include <iostream>
using namespace std;
int main()
{
// 请在此输入您的代码
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++)
cin >> arr[i];
//以后碰到这种移位的题目,统一用双指针,先用一个指针,把所有非0的数字往前移,再从指针的位置补上0
int j = 0;
for (int i = 0; i < n; i++) //j作为判断的指针
{
if (arr[i]) arr[j++] = arr[i];
}
while(j < n) arr[j++] = 0;
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
return 0;
}
方法二:遇到就输出
既然我们要保存非0的相对位置不变,但又需要把0全放在后面,那我们不妨遍历一遍数组,碰到非0的数字就输出,在这过程中计数,最后把0的数目输出出来
#include <iostream>
using namespace std;
int main()
{
// 请在此输入您的代码
int n;
cin >> n;
int arr[n];
int cnt = 0;
for (int i = 0; i < n; i++)//读入
cin >> arr[i];
for(int i = 0; i < n; i++)//碰到就输出
{
if (arr[i]) {
cout << arr[i] << " ";
cnt++;
}
}
while(cnt < n)//把0补全
{
cout << 0 << " ";
cnt++;
}
return 0;
}
方法三(不推荐):遇到0的时候将0移动到最后一位,并且将所有数字往前移动一格
这种方法对性能的开销大,因为要移动数组,数组如果很大就不好了,当然对于这道题数字很小,可以这么做。这种方法有一个值得注意的点,就是当0连续存在的时候,你需要做一些保守的判断,不然会遗漏掉0.
#include <iostream>
using namespace std;
int main()
{
// 请在此输入您的代码
int n;
cin >> n;
int arr[n];
int cnt = 0; //统计0出现了多少次
for (int i = 0; i < n; i++)//读入
cin >> arr[i];
for (int i = 0; i < n - cnt; i++) //这里i要走过n-cnt个,把0排除掉,不然进入死循环
{
if (arr[i] == 0)
{
for (int j = i; j < n - 1; j++) {
arr[j] = arr[j + 1];
}
arr[n - 1] = 0;
i--; //i--很重要,这是一个保守判断,排除有连续的0的情况
cnt++; //这里cnt是标记0的个数
}
}
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
return 0;
}
这里如果搞不明白为什么i--有这个作用,可以看我的另一篇题解,里面有详细解释i--的作用
PTA习题8-6删除字符(20分)(两种思路)_本题要求实现一个删除字符串中的指定字符的简单函数。-CSDN博客