您的位置:首页 > 其它

LeetCode-Easy部分中标签为Array#414 : Third Maximum Number

2017-03-29 13:19 597 查看

原题

Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n).

Example 1:

Input: [3, 2, 1]

Output: 1

Explanation: The third maximum is 1.

Example 2:

Input: [1, 2]

Output: 2

Explanation: The third maximum does not exist, so the maximum (2) is returned instead.

Example 3:

Input: [2, 2, 3, 1]

Output: 1

Explanation: Note that the third maximum here means the third maximum distinct number.

Both numbers with value 2 are both considered as second maximum.

题目分析

找出第3个最大的,如果不存在第3个最大,返回当前最大。利用 .NET的Linq解题。

代码

public int GetThirdMax(int[] a)
{
int first = a.Max();
int[] a2 = a.Where(r => r != first).ToArray();
if (a2.Length == 0)
return first;
int second = a2.Max();
int[] a3 = a2.Where(r => r != second).ToArray();
if (a3.Length == 0)
return first;
return a3.Max();
}


题目延伸

找出第n个最大值,下面是代码,只用数组实现,不借助其他数据结构。新建一个NthMax对象,提供的API有2个,如下所示,

//插入元素到对象中
public void Insert(int target);
//报告第n个最大值
public int Nth{get;}


使用对象方法:

int[] a = new int[] { 1,2,6,7,8,9,0 };
NthMax myNth = new NthMax(5);
foreach (var item in a)
{
myNth.Insert(item);
}
int thirdMax = myNth.Nth;


对象完整实现源码:

/// <summary>
/// NthMax
/// </summary>
public class NthMax
{
#region 构造函数
public NthMax(int nth)
{
_nth = nth;
}
#endregion

#region 属性字段
private int[] _maxVals;
private int _nth;
#endregion

#region 私有方法
/// <summary>
/// 如果target不在_maxVals中,则找到它的插入位置;如果在直接返回-1
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
private int searchInsertPos(int target)
{
int lo = 0;
int hi = _maxVals.Length;
while (lo < hi)
{
int mi = (lo + hi) >> 1;
if (target < _maxVals[mi]) //目标值不大于中间位置的数时,hi变小
hi = mi;
else if (target == _maxVals[mi])
return -1;
else if (target > _maxVals[mi]) //大于中间位置的值,lo加1
lo = lo + 1;
}
return lo;
}

/// <summary>
/// 在有序数组index处插入目标元素target
/// </summary>
/// <param name="index"></param>
/// <param name="target"></param>
private void insertAt(int index, int target)
{
int[] tmp = new int[_maxVals.Length + 1];
for (int i = 0; i < index; i++)
{
tmp[i] = _maxVals[i];
}

tmp[index] = target;

for (int i = index; i < _maxVals.Length; i++)
{
tmp[i + 1] = _maxVals[i];
}
_maxVals = tmp;
}

/// <summary>
/// 从beginIndex开始覆盖性后移1步
/// </summary>
/// <param name="beginIndex"></param>
private void moveBackward(int beginIndex)
{
if (beginIndex < 1)
return;
for (int i = 1; i <= beginIndex; i++)
{
_maxVals[i - 1] = _maxVals[i];
}
}

#endregion

#region 公有方法

public int Nth
{
get
{
return _maxVals.Length < _nth ?
_maxVals[_maxVals.Length - 1] : _maxVals[0];
}
}

/// <summary>
///
/// </summary>
/// <param name="target"></param>
public void Insert(int target)
{
if (_maxVals == null)
{
_maxVals = new int[1];
_maxVals[0] = target;
return;
}
if (_maxVals.Length < _nth)
{
int insertPos = searchInsertPos(target);
if (insertPos != -1)
{
insertAt(insertPos, target);
}
}
else if (_maxVals.Length == _nth)
{
int insertPos = searchInsertPos(target);
if (insertPos > 0)
{
if (insertPos == 0)
insertPos = 0;
moveBackward(insertPos - 1);
_maxVals[insertPos - 1] = target; //在空出来的位置处插入目标元素
}
}
}
#endregion

}


更多的leetcode

LeetCode-题目按tag分类

LeetCode-Easy部分中标签为Array的所有题目
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: