需求描述:已知一个长度为100的int型数组,并且每个元素的值大于等于1,并小于等于100,写出一个函数,判断该数组中是否存在重复元素。
这个是大概2年前参加面试的一道算法题,不算难,相信大家都有了自己的一个解法,但怎样才算具有最少时间复杂度和最小空间复杂度的解法呢?
class ArrayFindRepeat
{
private int[] _arr;
public ArrayFindRepeat(int[] arr)
{
this._arr = arr;
}
}
方法一
/// <summary>
/// 最普通的思路,把每个元素和数组本身遍历一次
/// </summary>
/// <returns></returns>
public bool IsContainRepeat1()
{
for (int i = 0; i < _arr.Length; i++)
{
for (int j = 0; j < _arr.Length; j++)
{
if (j != i) //排除依次循环的元素本身
{
if (_arr[j] == _arr[i])
return true;
}
}
}
return false;
}
方法二
/// <summary>
/// 先排序,再遍历每个元素
/// </summary>
/// <returns></returns>
public bool IsContainRepeat2()
{
var newArr = (from a in _arr
orderby a ascending
select a).ToArray();
for (int i = 0; i < newArr.Length; i++)
{
if (newArr[i] != i + 1)
return true;
}
return false;
}
方法三
/// <summary>
/// 使用哈希表键不能重复的特性
/// </summary>
/// <returns></returns>
public bool IsContainRepeat3()
{
HashSet<int> ht = new HashSet<int>();
foreach (int i in _arr)
{
if (!ht.Add(i))
{
return true;
}
}
return false;
}
方法四
/// <summary>
/// 满足条件的数组只有一种情况,就是1-100,使用临时数组,做标记位的方法
/// </summary>
/// <returns></returns>
public bool IsContainRepeat4()
{
int[] temp = new int[_arr.Length + 1];
for (int i = 0; i < _arr.Length; i++)
{
int a = _arr[i];
if (temp[a] != 0)
{
return true;
}
else
{
temp[a] = 1;
}
}
return false;
}
相信一定有更简单的解法,欢迎大家拍砖。