leetcode- 215. Kth Largest Element in an Array(基于插入排序思想)

来源:互联网 发布:数码宝贝网络侦探练级 编辑:程序博客网 时间:2024/06/06 09:56

原题

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

For example,

Given [3,2,1,5,6,4] and k = 2, return 5.

Note:
You may assume k is always valid, 1 ≤ k ≤ array’s length.

代码分析

求无序数组(可能含有重复元素)的第 K 个最大值。提供一种基于插入排序的求解方法。

基于插入排序求Kth最大值

调用自己写的 NthMax类的过程,这个方法相对繁琐一些。

    public int FindKthLargest(int[] nums, int k)     {            NthMax myNth = new NthMax(k);            foreach (var item in nums)            {                myNth.Insert(item);            }            return myNth.Nth;    }

API 实现细节:

        public class NthMax        {            //构造函数            public NthMax(int nth)            {                _nth = nth;            }            //第n个最大值               public int Nth            {                get                {                    int dis = _maxVals.Length-_nth;                    return _maxVals[dis];                }            }            public void Insert(int target)            {                if (_maxVals == null)                {                    _maxVals = new int[1];                    _maxVals[0] = target;                    return;                }                if (_maxVals.Length < _nth)                {                    int insertPos = searchInsertPos(target);                    insertAt(insertPos, target);                }                else if (_maxVals.Length == _nth)                {                    int insertPos = searchInsertPos(target);                    if (insertPos > 0)                    {                        moveBackward(insertPos - 1);                        _maxVals[insertPos - 1] = target; //在空出来的位置处插入目标元素                    }                }            }         

私有方法:

   private int[] _maxVals;            private int _nth;            // 如果target不在_maxVals中,则找到它的插入位置;如果在直接返回-1            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 = mi;                    else  //不小于中间位置的值                        lo = lo + 1;                }                return lo;            }            //在有序数组index处插入目标元素target            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;            }            // 从beginIndex开始覆盖性后移1步            private void moveBackward(int beginIndex)            {                if (beginIndex < 1)                    return;                for (int i = 1; i <= beginIndex; i++)                {                    _maxVals[i - 1] = _maxVals[i];                }            }        }
2 0