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

原题

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的所有题目

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值