下面有四个问题:

  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. Nginx + uWSGI 部署Django 项目,并实现负载均衡

    一.uWSGI服务器 uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换. 要注意 WSGI ...

  2. dfs找負環

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

  3. FunDA(6)- Reactive Streams:Play with Iteratees、Enumerator and Enumeratees

    在上一节我们介绍了Iteratee.它的功能是消耗从一些数据源推送过来的数据元素,不同的数据消耗方式代表了不同功能的Iteratee.所谓的数据源就是我们这节要讨论的Enumerator.Enumer ...

  4. CSS3的三大特性

    在学习CSS 的时候,我们必须要熟练和理解CSS 的三大特性,那么CSS 的三大特性又是什么呢? CSS 的三大特性:层叠 继承 优先级  ,CSS 三大特性是我们学习CSS 必须掌握的三个特性. 首 ...

  5. Python小白学习之路(六)—— 【元祖】【元祖相关功能】

    元祖 tu = (111,'alex',(11,['aa','xhg',(78,43)],'aaa'),789,) 通过这个例子,我们看到元祖的特征: 是通过括号()括起来的 一般写元祖的时候,推荐子 ...

  6. appt查看应用包报名和入口页面

    appt在哪里? aapt不需要另外安装喔,有安装了adt的,可以直接在adt../sdk/build-tools/android-xx/下,找到aapt,详细路径如图 怎么使用aapt.bat? 直 ...

  7. POJ 2392

    #include <iostream> #include <algorithm> #define MAXN 40005 using namespace std; struct ...

  8. 51单片机SRF寄存器

    1.21个寄存器介绍        51系列单片机内部主要有四大功能模块,分别是I/O口模块.中断模块.定时器模块和串口通信模块(串行I/O口),如其结构和功能如下图: 图1 51单片机结构和功能图 ...

  9. VUE输入框显示时自动聚焦

    directives: { focus: { inserted: function (el, {value}) { if (value) { el.focus() } } } } 注意点:1.用v-i ...

  10. 【链表】Rotate List(三个指针)

    题目: Given a list, rotate the list to the right by k places, where k is non-negative. For example:Giv ...