第K大元素问题
public static int kthLargestElement(int k, int[] nums)
{
    //两个哨兵ij,temp为临时值,start和end记录具体查找段的开始和结束
    int i, j, temp, start, end;
    
    //初始化值
    bool isEnd = false;
    i = 0;
    start = i;
    j = nums.Length - 1;
    end = j;
    temp = -1;

    if (nums.Length < k) return -1;

    //快排思想,但是不用管非目标段的排序
    while (!isEnd)
    {
        //处理每一段的排序,将比参考值小的往前靠,比参考值大的往后靠,参考值放中间
        temp = start;
        while (i != j)
        {
            while (nums[j] <= nums[temp] && j != i)
            {
                j--;//在右边找一个比参考值小的
            }

            while (nums[i] >= nums[temp] && i != j)
            {
                i++;//在左边找一个比参考值大的
            }

            if (i == j)
            {
                //两哨兵相遇,与参考值调换位置
                if (i != temp)//注意这两个相等的时候,这种交换就把值变成0了
                {
                    nums[i] = nums[i] + nums[temp];
                    nums[temp] = nums[i] - nums[temp];
                    nums[i] = nums[i] - nums[temp];
                }
                temp = i;
            }
            else
            {
                //交换两个找到的值
                nums[i] = nums[i] + nums[j];
                nums[j] = nums[i] - nums[j];
                nums[i] = nums[i] - nums[j];
            }
        }

        //判断是否找到了,参考的位置就是该数据的真实排名了
        if (temp + 1 == k)
        {
            isEnd = true;
            break;
        }

        if (temp + 1 < k)
        {
            //去右边
            j = end;
            start = temp + 1;
            i = temp + 1;
        }
        else
        {
            i = start;
            end = temp - 1;
            j = temp - 1;
        }

    }

    return nums[temp];
}


原来这叫Quick Select,和快排是同一个人提出的。

注释已经写得很明白了 也可以参考 快速排序-不用List速排序-不Lis


首页 我的博客
粤ICP备17103704号