下面有四个问题:

  1. 把数组元素前后部分交换 MoveFirstPartOfArrayToTheEnd(int[] array, int index) 比如 {1,2,3,4,5,6,7} 3  => {4,5,6,7,1,2,3}
  2. 把数组元素前后部分交换 MoveFirstPartOfArrayToTheEnd(int[]  array, int value)比如 {1,2,8,4,5,6,7} 8  => {4,5,6,7,1,2,8}
  3. 把数组一段移动到后面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}
  4. 把数组中重复的元素变成0放到最后面RemoveDulplicatedElements(int[] array) 比如 {1,3,3,2,4,4,4,5} => {1,3,2,4,5,0,0,0}

你首先想到的办法是什么?

  1. 申请一个临时数组把FistPart和EndPart交换
  2. 同上,只要找到对应值的下标即可。
  3. 同上申请临时数组,把要移动的段放到临时数组里
  4. 申请一个临时的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. 我们先看{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}。
  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}
  4. {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#实现的更多相关文章

  1. PTA 数组元素的区间删除

    6-6 数组元素的区间删除 (20 分)   给定一个顺序存储的线性表,请设计一个函数删除所有值大于min而且小于max的元素.删除后表中剩余元素保持顺序存储,并且相对位置不能改变. 函数接口定义: ...

  2. java 在循环中删除数组元素

    在写代码中经常会遇到需要在数组循环中删除数组元素的情况,但删除会导致数组长度变化. package com.fortunedr.thirdReport; import java.util.ArrayL ...

  3. JS数组方法汇总 array数组元素的添加和删除

    js数组元素的添加和删除一直比较迷惑,今天终于找到详细说明的资料了,先给个我测试的代码^-^ var arr = new Array(); arr[0] = "aaa"; arr[ ...

  4. 几种php 删除数组元素方法

    几种php教程 删除数组元素方法在很多情况下我们的数组会出现重复情况,那我们删除数组中一些重复的内容怎么办,这些元素我必须保持他唯一,所以就想办法来删除它们,下面利用了遍历查询来删除重复数组元素的几种 ...

  5. Javascript:splice()方法实现对数组元素的插入、删除、替换及去重

    定义和用法 splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目. 注释:该方法会改变原始数组. 语法: Array.prototype.splice(index,count[,el ...

  6. 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.数组插入.删除 ...

  7. jQuery根据元素值或元素下标来删除一个数组元素及数组对象方法列表

    在前提不知道b在这个数组的下标,删除b这个元素  var arrList = ['a','b','c','d'];         arrList.splice(jQuery.inArray('b', ...

  8. js删除数组元素

    一.清空数组 var ary = [1,2,3,4]; ary.splice(0,ary.length);//清空数组 console.log(ary); // 输出 [],空数组,即被清空了 二.删 ...

  9. js删除数组元素、清空数组的简单方法

    一.清空数组 ? 1 2 3 var ary = [1,2,3,4]; ary.splice(0,ary.length);//清空数组 console.log(ary); // 输出 [],空数组,即 ...

随机推荐

  1. D - 统计同成绩学生人数

    点击打开链接 读入N名学生的成绩,将获得某一给定分数的学生人数输出.  Input 测试输入包含若干测试用例,每个测试用例的格式为  第1行:N  第2行:N名学生的成绩,相邻两数字用一个空格间隔.  ...

  2. dfs找負環

    某些無良出題人可能會卡bfs找負環,所以要用dfs 核心代碼(以jzoj5173為例): #include<bits/stdc++.h> using namespace std; #def ...

  3. Django准备知识-web应用、http协议、web框架、Django简介

    一.web应用 Web应用程序是一种可以通过web访问的应用程序(web应用本质是基于socket实现的应用程序),程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件 ...

  4. Django安装(第一个项目)

    day60 从系统中选择已存在的解释器. 新建Django项目         命令行创建:             django-admin startproject mysite          ...

  5. strlen()与mb_strlen()的区别

    1,strlen()是php的内置函数,可以在php中直接调用:mb_strlen()是php的扩展,需要配置php.ini,以开启mb_strlen()扩展.在php.ini中加载了php_mbst ...

  6. nginx请求频率限制模块ngx_http_limit_req_module

    模块: ngx_http_limit_req_module 作用: 限制客户端请求频率,防止恶意攻击 配置示例: http { limit_req_zone $binary_remote_addr z ...

  7. 为什么有监听socket和连接socket,为什么产生两个socket

    为什么有监听socket和连接socket,为什么产生两个socket 先看一半的socket建立连接的双方的过程: 客户端: socket()---->创建出 active_socket_fd ...

  8. Jmeter服务器监控 serveragent如何使用

    安装jmeter插件Plugins Managerjmeter-plugins.org推出了全新的Plugins Manager,对于其提供的插件进行了集中的管理,我们只需要安装这个管理插件,即可以在 ...

  9. JavaWeb之Servlet中ServletConfig和ServletContext

    [声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140877.html [正文] 一.ServletConfig:代表当前 ...

  10. Lingo 做线性规划 - Financial Applications

    Reference: <An Introduction to Management Science Quantitative Approaches to Decision Making, Rev ...