数组元素的移动(删除) C#实现
下面有四个问题:
- 把数组元素前后部分交换 MoveFirstPartOfArrayToTheEnd(int[] array, int index) 比如 {1,2,3,4,5,6,7} 3 => {4,5,6,7,1,2,3}
 - 把数组元素前后部分交换 MoveFirstPartOfArrayToTheEnd(int[] array, int value)比如 {1,2,8,4,5,6,7} 8 => {4,5,6,7,1,2,8}
 - 把数组一段移动到后面MoveSomeElementsToTheEnd(int[] array, int startIndex, int length)比如{1,2,3,4,5,6,7,8} 3 3 => {1,2,3,7,8,4,5,6}
 - 把数组中重复的元素变成0放到最后面RemoveDulplicatedElements(int[] array) 比如 {1,3,3,2,4,4,4,5} => {1,3,2,4,5,0,0,0}
 
你首先想到的办法是什么?
- 申请一个临时数组把FistPart和EndPart交换
 - 同上,只要找到对应值的下标即可。
 - 同上申请临时数组,把要移动的段放到临时数组里
 - 申请一个临时的List<int>把唯一的元素加到List里面,再重新赋给Array。
 
class Program
{
static void Main(string[] args)
{
//
int[] array1 = { , , , , , , };
MoveFirstPartOfArrayToTheEnd(array1, );
printArray(array1); //
int[] array2 = { , , , , , , };
MoveFirstPartOfArrayToTheEndValue(array2, );
printArray(array2); //
int[] array3 = { , , , , , , , };
MoveSomeElementsToTheEnd(array3, , );
printArray(array3); //
int[] array4 = { , , , , , , , };
removeDulplicatedElements(array4);
printArray(array4); } private static void printArray(int[] array)
{
for (int i = ; i < array.Length; i++)
{
Console.Write(array[i]);
}
Console.WriteLine();
} public static void MoveFirstPartOfArrayToTheEnd(int[] array, int index)
{
if (index >= array.Length || index <= )
{
throw new Exception("index must be greater than 0 and less than " + array.Length);
} //Move the first part of array to a temp array
int[] temp = new int[index];
for (int i = ; i < index; i++)
{
temp[i] = array[i];
} //Move forward the other element
for (int i = ; i < array.Length - index; i++)
{
array[i] = array[i + index];
} //Move the first part back to the end of array
int j = ;
for (int i = array.Length - index; i < array.Length; i++)
{
array[i] = temp[j];
j++;
}
} public static void MoveFirstPartOfArrayToTheEndValue(int[] array, int value)
{
bool move = false; //Search the value in the array
for (int i = ; i < array.Length; i++)
{
if (array[i] == value)
{ //Move the first part if we find the value
MoveFirstPartOfArrayToTheEnd(array, i + );
move = true;
break;
}
} if (!move)
{
throw new Exception("No matched value is found in the array");
}
} public static void MoveSomeElementsToTheEnd(int[] array, int startIndex, int length)
{
if (startIndex < || startIndex >= array.Length - )
{
throw new Exception("startIndex must be greater than 0 and less than " + (array.Length - ).ToString());
} if (startIndex + length + > array.Length)
{
throw new Exception("Please provide a valid length");
} int[] temp = new int[length];
for (int i = ; i < temp.Length; i++)
{
temp[i] = array[startIndex + i];
} //Move forward the other element
for (int i = startIndex; i < array.Length - length; i++)
{
array[i] = array[i + length];
} //Move the first part back to the end of array
int k = ;
for (int i = array.Length - length; i < array.Length; i++)
{
array[i] = temp[k];
k++;
}
} public static void removeDulplicatedElements(int[] array)
{
List<int> temp = new List<int>();
for (int i = ; i < array.Length; i++)
{
if (array[i] == )
continue;
temp.Add(array[i]);
for (int j = i + ; j < array.Length; j++)
{
if (array[i] == array[j])
{
array[j] = ;
}
}
} for (int i = ; i < array.Length; i++)
{
if (i < temp.Count)
{
array[i] = temp[i];
}
else
{
array[i] = ;
}
}
}
}
现在要求优化算法,空间复杂度为O(1),该如何去优化呢?
- 我们先看{1,2,3,4,5,6,7}3如何变成{4,5,6,7,1,2,3}的,首先前后部分各自反转变成{3,2,1,7,6,5,4}然后再把整个数组反转就变成了{4,5,6,7,1,2,3}。
 - 同上,只要找到对应值的下标即可。
 - 我们再看{1,2,3,4,5,6,7,8} 3 3 => {1,2,3,7,8,4,5,6}过程,前面不动的部分{1,2,3}先不管,且看后面{4,5,6,7,8}=>{7,8,4,5,6},同上面,各自反转尔后整体反转{6,5,4,8,7}=>{7,8,4,5,6}
 - {1,3,3,2,4,4,4,5} => {1,3,2,4,5,0,0,0}的过程,先把重复的元素变成0,再依次移动到最后,{1,3,3,2,4,4,4,5} => {1,3,0,2,4,0,0,5}=>{1,3,2,4,0,0,5,0}=>{1,3,2,4,0,5,0,0}=>{1,3,2,4,5,0,0,0}
 
从上面可以看出都用到了一个通用的方法就是反转数组ReversArray().这个操作只需要申请一个临时变量。即空间复杂度为O(1)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace TransposeArray
{
class Program
{
static void Main(string[] args)
{
//1 {1,2,3,4,5,6,7} 3 => {4,5,6,7,1,2,3}
int[] Array1 = new int[] { , , , , , , };
TransposeByIndex(Array1, );
PrintArray(Array1);
//2 {1,2,8,4,5,6,7} 8 => {4,5,6,7,1,2,8}
int[] Array2 = new int[] { , , , , , , };
TransposeByValue(Array2, );
PrintArray(Array2);
//3 {1,2,3,4,5,6,7,8} 3 3 => {1,2,3,7,8,4,5,6}
int[] Array3 = new int[] { , , , , , , , };
TransposeBySegment(Array3, , );
PrintArray(Array3);
//4 {1,3,3,2,4,4,4,5} => {1,3,2,4,5,0,0,0}
int[] Array4 = new int[] { , , , , , , , };
RemoveDuplicated(Array4);
PrintArray(Array4);
} //Print the array.
public static void PrintArray(int[] array)
{
for (int i = ; i < array.Length; i++)
{
Console.Write(array[i] + ", "); }
Console.ReadLine();
} // Reverse an Array
public static void ReverseArray(int[] array, int left, int right)
{ for (; left < right; ++left, --right)
{
int tmp = array[left];
array[left] = array[right];
array[right] = tmp;
}
} // Reverse thrice respectively.
public static void TransposeByIndex(int[] array, int index)
{
ReverseArray(array, , index);
ReverseArray(array, index + , array.Length - );
ReverseArray(array, , array.Length - );
} //Transpose by value
public static void TransposeByValue(int[] array, int value)
{
for (int i = ; i < array.Length; i++)
if (array[i] == value)
{
TransposeByIndex(array, i);
}
} //Tanspose by segment
public static void TransposeBySegment(int[] array, int StartIndex, int Length)
{
int div = StartIndex + Length - ;
int end = array.Length - ;
ReverseArray(array, StartIndex, div);
ReverseArray(array, div + , end);
ReverseArray(array, StartIndex, end);
} //Romove duplicated Elements
public static void RemoveDuplicated(int[] array)
{
for (int i = array.Length - ; i > ; i--)
{
for (int j = ; j < i; j++)
{
if (array[i] == array[j])
{
array[i] = ;
}
} } for (int i = ; i < array.Length - ; i++)
{
for (int j = array.Length - ; j > i; j--)
{
if (array[i] == && array[j] != )
{
ReverseArray(array, i, j);
ReverseArray(array, i, j - );
}
}
} }
}
}
第4个问题可以用其他方法实现,不去调用ReversArray方法。
找到重复元素置为0,然后搜索为0的值,再把后面的元素前移,最后一个元素置0。空间复杂度也为O(1)
数组元素的移动(删除) C#实现的更多相关文章
- PTA  数组元素的区间删除
		
6-6 数组元素的区间删除 (20 分) 给定一个顺序存储的线性表,请设计一个函数删除所有值大于min而且小于max的元素.删除后表中剩余元素保持顺序存储,并且相对位置不能改变. 函数接口定义: ...
 - java 在循环中删除数组元素
		
在写代码中经常会遇到需要在数组循环中删除数组元素的情况,但删除会导致数组长度变化. package com.fortunedr.thirdReport; import java.util.ArrayL ...
 - JS数组方法汇总 array数组元素的添加和删除
		
js数组元素的添加和删除一直比较迷惑,今天终于找到详细说明的资料了,先给个我测试的代码^-^ var arr = new Array(); arr[0] = "aaa"; arr[ ...
 - 几种php 删除数组元素方法
		
几种php教程 删除数组元素方法在很多情况下我们的数组会出现重复情况,那我们删除数组中一些重复的内容怎么办,这些元素我必须保持他唯一,所以就想办法来删除它们,下面利用了遍历查询来删除重复数组元素的几种 ...
 - Javascript:splice()方法实现对数组元素的插入、删除、替换及去重
		
定义和用法 splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目. 注释:该方法会改变原始数组. 语法: Array.prototype.splice(index,count[,el ...
 - javascript 常见数组操作( 1、数组整体元素修改  2、 数组筛选  3、jquery 元素转数组  4、获取两个数组中相同部分或者不同部分  5、数组去重并倒序排序  6、数组排序  7、数组截取slice  8、数组插入、删除splice(需明确位置)  9、数组遍历  10、jQuery根据元素值删除数组元素的方)
		
主要内容: 1.数组整体元素修改 2. 数组筛选 3.jquery 元素转数组 4.获取两个数组中相同部分或者不同部分 5.数组去重并倒序排序 6.数组排序 7.数组截取slice 8.数组插入.删除 ...
 - jQuery根据元素值或元素下标来删除一个数组元素及数组对象方法列表
		
在前提不知道b在这个数组的下标,删除b这个元素 var arrList = ['a','b','c','d']; arrList.splice(jQuery.inArray('b', ...
 - js删除数组元素
		
一.清空数组 var ary = [1,2,3,4]; ary.splice(0,ary.length);//清空数组 console.log(ary); // 输出 [],空数组,即被清空了 二.删 ...
 - js删除数组元素、清空数组的简单方法
		
一.清空数组 ? 1 2 3 var ary = [1,2,3,4]; ary.splice(0,ary.length);//清空数组 console.log(ary); // 输出 [],空数组,即 ...
 
随机推荐
- zoj4019 Schrödinger's Knapsack(dp)
			
题意:有两种物品分别为n,m个,每种物品对应价值k1,k2.有一个容量为c的背包,每次将一个物品放入背包所获取的价值为k1/k2*放入物品后的剩余体积.求问所获取的最大价值. 整体来看,优先放入体积较 ...
 - fluentd 推送 mariadb audit log
			
说明: mariadb audit log是 mariadb 的审计日志 目的是把日志拆分成 tab 键分隔的字段 直接附上 fluentd 配置文件 <system> log_level ...
 - nginx代理websocket协议
			
以下是代码段.location /wsapp/ { proxy_pass http://wsbackend; proxy_http_version 1.1; proxy_set ...
 - 初识PHP之php运行流程及原理(一)
			
初识PHP一.用脚本命令行运行php(1)打开cmd.exe(winkey+R)(2)找到php.exe(拖进cmd即可)(3)输入命令php.exe -f "文件实际路径"注:运 ...
 - Hbuilder用ajax连接eclipse中的servlet例子以及注意事项
			
今天用前端神器Hbuilder连接eclipse中的servlet,真是费了九牛二虎之力,才把问题解决 Hbuilder中的代码: test.html <!DOCTYPE html> &l ...
 - iOS开发证书与配置文件的使用
			
前提 众所周知,开发iOS应用必须要有iOS证书(Certificates)和配置文件(Provisioning Profiles),那么问题来了: 1.什么是iOS证书,它是如何与app应用关联的? ...
 - JavaScript 常见使用误区
			
JavaScript 常见使用误区,都是平时开发过程中填过的一些坑,整理记录下. 比较运算符常见错误 //在常规的==比较中,数据类型是被忽略的,以下 if 条件语句返回 true: var x = ...
 - Linux开发端口的基本操作命令
			
Linux端口操作命令 查看开放端口:firewall-cmd --list-all 开发8080端口 --permanent 代码永久开发:firewall-cmd --add-port=8080/ ...
 - (转)ldd 查看程序依赖库
			
原文:https://blog.csdn.net/u010977122/article/details/52993560?spm=a2c4e.11153940.blogcont551034.8.4f7 ...
 - Java之IO(三)ByteArrayInputStream和ByteArrayOutputStream
			
转载请注明源出处:http://www.cnblogs.com/lighten/p/6972297.html 1.前言 这组输入输出流比较特殊,一般的流指定都是磁盘IO和网络IO,从文件中读取数据或者 ...