Acwing 快速排序

182 阅读3分钟

1、 快速排序 题目: leetcode-cn.com/problems/so…

给你一个整数数组 nums,请你将该数组升序排列。

示例 1:

输入:nums = [5,2,3,1] 输出:[1,2,3,5]

// 自己写的代码记得更熟一点
class Solution {
    public int[] sortArray(int[] nums) {
        // 开头检查就是废话了
        if(nums == null || nums.length == 0 || nums.length == 1){
            return nums;
        }
        partition(nums, 0, nums.length - 1);
        return nums;
    }

    public void partition(int[] nums, int start, int end){
        // 递归退出条件
        if(start >= end){
            return;
        }
        int left = start;
        int right = end;
        /*
          首先从右边往左边扫,找小的
          然后左边往右边扫,找大的
          两边一直换,一直到左右相遇
          从最外层的while(left < right)可以判断最后停下来的时候
          应该是left == right,无论哪层循环条件都是left < right才能推动,只要这个不满足了就不会走了
          但是left总是可以保证小于等于start,如果left是从右边换过来的就一定小,如果没换过就是start本身
        */
        while(left < right){
            while(left < right && nums[right] >= nums[start]){right--;}
            while(left < right && nums[left] <= nums[start]){left++;}
            // 这里面是左右换
            swap(nums, left, right);
        }
        // 当左右重合了之后,左边的一定小于等于start,换了没风险
        swap(nums, right, start); 
        partition(nums, start, right - 1);
        partition(nums,right + 1, end);
    }
    public void swap(int[] nums, int left, int right){
        int tem = nums[left];
        nums[left] = nums[right];
        nums[right] = tem;
    }
}

2、 数组中的第K个最大元素

题目: leetcode-cn.com/problems/kt…

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2 输出: 5 示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4 输出: 4

class Solution {
    public int findKthLargest(int[] nums, int k) {
        if(nums == null || nums.length < k){
            return 0;
        }
        return findKthLargest(nums, 0, nums.length - 1, nums.length - k);
    }

    public int findKthLargest(int[] nums, int start, int end, int k){
        int left = start;
        int right = end;
        while(left < right){
            while(left < right && nums[right] >= nums[start]){right--;}
            while(left < right && nums[left] <= nums[start]){left++;}
            swap(nums,left,right);
        }
        // 感觉这里麻烦就麻烦在left和right指针停止的位置上
        swap(nums,left,start);
        if(left == k){return nums[k];}
        if(left < k){
            return findKthLargest(nums, left + 1, end, k);
        }else{
            return findKthLargest(nums,start, left - 1, k);
        }
    }

    public void swap(int[] nums, int left, int right){
        int tem = nums[left];
        nums[left] = nums[right];
        nums[right] = tem;
    }
}

3、 七夕祭

题目: www.acwing.com/problem/con…

七夕节因牛郎织女的传说而被扣上了「情人节」的帽子。

于是 TYVJ 今年举办了一次线下七夕祭。

Vani 同学今年成功邀请到了 cl 同学陪他来共度七夕,于是他们决定去 TYVJ 七夕祭游玩。

TYVJ 七夕祭和 11 区的夏祭的形式很像。

矩形的祭典会场由 N 排 M 列共计 N×M 个摊点组成。

虽然摊点种类繁多,不过 cl 只对其中的一部分摊点感兴趣,比如章鱼烧、苹果糖、棉花糖、射的屋……什么的。

Vani 预先联系了七夕祭的负责人 zhq,希望能够通过恰当地布置会场,使得各行中 cl 感兴趣的摊点数一样多,并且各列中 cl 感兴趣的摊点数也一样多。

不过 zhq 告诉 Vani,摊点已经随意布置完毕了,如果想满足 cl 的要求,唯一的调整方式就是交换两个相邻的摊点。

两个摊点相邻,当且仅当他们处在同一行或者同一列的相邻位置上。

由于 zhq 率领的 TYVJ 开发小组成功地扭曲了空间,每一行或每一列的第一个位置和最后一个位置也算作相邻。

现在 Vani 想知道他的两个要求最多能满足多少个。

在此前提下,至少需要交换多少次摊点。

输入格式 第一行包含三个整数 N 和 M 和 T,T 表示 cl 对多少个摊点感兴趣。

接下来 T 行,每行两个整数 x,y,表示 cl 对处在第 x 行第 y 列的摊点感兴趣。

输出格式 首先输出一个字符串。

如果能满足 Vani 的全部两个要求,输出 both;

如果通过调整只能使得各行中 cl 感兴趣的摊点数一样多,输出 row;

如果只能使各列中 cl 感兴趣的摊点数一样多,输出 column;

如果均不能满足,输出 impossible。

如果输出的字符串不是 impossible, 接下来输出最小交换次数,与字符串之间用一个空格隔开。

数据范围 1≤N,M≤100000, 0≤T≤min(N∗M,100000), 1≤x≤N, 1≤y≤M 输入样例: 2 3 4 1 3 2 1 2 2 2 3 输出样例: row 1