BM47-寻找第K大

题目

有一个整数数组,请你根据快速排序的思路,找出数组中第 k 大的数。

给定一个整数数组 a ,同时给定它的大小n和要找的 k ,请返回第 k 大的数(包括重复的元素,不用去重),保证答案存在。

要求:时间复杂度 O(nlogn),空间复杂度 O(1)。

数据范围:0≤n≤1000, 1≤K≤n,数组中每个元素满足 0≤val≤10000000。

示例1

输入:[1,3,5,2,2],5,3

返回值:2

示例2

输入:[10,10,9,9,8,7,5,6,4,3,4,2],12,3

返回值:9

说明:去重后的第3大是8,但本题要求包含重复的元素,不用去重,所以输出9。


思路

快排分区partition思想,当分区函数返回的索引值 = n - k,该分区元素就是要找的元素。时间复杂度O(n)。


代码

import java.util.*;

public class Solution {
    public int findKth(int[] a, int n, int K) {
        //第k大元素的索引为n - k
        //[1,2,3,4,5]第2大元素4对应的索引为5 - 2 = 3
        return findKthLargestInternal(a, 0, a.length - 1, a.length - K);
    }

    /**
     * 在nums[l...r]找到索引为k元素
     * @param nums
     * @param l
     * @param r
     * @param k
     * @return
     */
    private int findKthLargestInternal(int[] nums, int l, int r, int k) {
        if (l > r) {
            //空区间
            return -1;
        }
        int p = partition(nums, l, r);
        if (p == k) {
            //此时索引p对应的元素恰好就是要查找的元素
            return nums[p];
        } else if (k > p) {
            //在右半区间接着找
            return findKthLargestInternal(nums, p + 1, r, k);
        }
        //此时k < p,在左半区间找
        return findKthLargestInternal(nums, l, p - 1, k);
    }

    /**
     * 分区函数
     * @param nums
     * @param l
     * @param r
     * @return
     */
    private int partition(int[] nums, int l, int r) {
        //默认选择第一个元素作为分区点
        int v = nums[l];
        //i是当前处理的元素
        //arr[l + 1...j] < v
        //最开始没有元素 < v
        int j = l;
        //arr[j + 1...i) >= v也是空区间
        for (int i = l + 1; i <= r; i++) {
            if (nums[i] < v) {
                swap(nums, j + 1, i);
                j++;
            }
        }
        //j对应 <v 的最后一个元素
        swap(nums, l, j);
        return j;
    }

    /**
     * 交换三连操作
     * @param nums
     * @param i
     * @param j
     */
    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: BM3D (Block-Matching 3D) 是一种图像去噪算法,适用于各种类型的图像,包括自然图像和医学图像等。该算法的主要思路是通过利用图像的统计信息来减少噪声,并通过块匹配和3D协同滤波来实现图像去噪。以下是BM3D算法的MATLAB代码示例: ```MATLAB % 读取图像 img = im2double(imread('input_image.jpg')); % 设置参数 h = 0.1; % 高斯滤波器的标准差 sigma = 0.05; % 噪声标准差 N = 8; % 块的大小 K = 16; % 最大块匹配数量 L = 8; % 3D协同滤波的邻居数量 lambda = 0.06; % 修复过程的拉格朗日乘子 % 图像预处理 preprocessed_img = img; preprocessed_img = padarray(preprocessed_img, [N, N], 'symmetric'); % 对图像进行对称填充 % 块匹配 block_num = floor(size(preprocessed_img) / N); for i = 1: block_num(1) for j = 1: block_num(2) block = preprocessed_img(((i - 1) * N + 1): (i * N), ((j - 1) * N + 1): (j * N)); matched_block = find_matched_block(block, preprocessed_img, K, sigma); matched_blocks{i, j} = matched_block; end end % 3D协同滤波 filtered_img = zeros(size(preprocessed_img)); for i = 1: block_num(1) for j = 1: block_num(2) matched_block = matched_blocks{i, j}; similar_blocks = find_similar_blocks(matched_block, matched_blocks, L, sigma); filtered_block = collaborative_filtering(matched_block, similar_blocks, lambda, sigma); filtered_img(((i - 1) * N + 1): (i * N), ((j - 1) * N + 1): (j * N)) = filtered_block; end end % 去除填充 filtered_img = filtered_img((N + 1): (end - N), (N + 1): (end - N)); % 显示和保存结果 figure; subplot(1, 2, 1); imshow(img); title('原图像'); subplot(1, 2, 2); imshow(filtered_img); title('去噪图像'); imwrite(filtered_img, 'denoised_image.jpg'); ``` 上述的代码包含了BM3D算法的主要步骤,其中还包括一些辅助函数的调用,如`find_matched_block`、`find_similar_blocks`和`collaborative_filtering`。这些函数的目的是分别寻找匹配的块、相似的块以及进行3D协同滤波。这些函数的具体实现可以根据需要进一步补充。希望以上代码对你有所帮助! ### 回答2: 以下是BM3D算法的MATLAB代码: ``` %% 1. 读取图像并进行加噪 original = imread('original_image.png'); % 原始图像 noisy = imread('noisy_image.png'); % 带噪图像 %% 2. BM3D图像去噪 denoised = BM3D(original, noisy); %% 3. 显示结果 imshow(original) title('原始图像') figure imshow(noisy) title('带噪图像') figure imshow(denoised) title('去噪图像') %% BM3D函数 function denoised_image = BM3D(original, noisy) % 参数设置 sigma = 20; % 噪声标准差 group_size = 16; % 块大小 patch_size = 8; % 图片块大小 threshold = 2.7*sigma; % 阈值 % 第一步:分组形成3D数据块 [h, w] = size(original); group = zeros(patch_size, patch_size, group_size); for i = 1:group_size x = unidrnd(w - patch_size + 1); y = unidrnd(h - patch_size + 1); group(:, :, i) = noisy(y:y+patch_size-1, x:x+patch_size-1); end % 第二步:相似3D块合并 similar_group = zeros(size(group)); for i = 1:group_size similar_group(:, :, i) = NonLocalMeans(group(:, :, i), sigma); end % 第三步:基本块去噪 basic = zeros(size(similar_group)); for i = 1:group_size basic(:, :, i) = WienerFilter(similar_group(:, :, i), sigma^2); end % 第四步:一致性(最终去噪结果) denoised_image = zeros(h, w); cnt = zeros(h, w); for k = 1:group_size for i = 1:patch_size for j = 1:patch_size denoised_image(y:y+patch_size-1, x:x+patch_size-1) = denoised_image(y:y+patch_size-1, x:x+patch_size-1) + basic(:, :, k); cnt(y:y+patch_size-1, x:x+patch_size-1) = cnt(y:y+patch_size-1, x:x+patch_size-1) + 1; end end end denoised_image = denoised_image ./ cnt; % 非局部均值函数 function similar_group = NonLocalMeans(group, sigma) % 实现非局部均值算法 % ... end %维纳滤波函数 function basic = WienerFilter(similar_group, sigma_sq) % 实现维纳滤波算法 % ... end end ``` 请注意,以上代码只是BM3D算法的一个简单演示,并未实现其完整功能。真正完整实现BM3D算法需要详细了解该算法的细节并进行具体编码实现。以上代码仅供参考。 ### 回答3: BM3D算法是一种用于图像降噪的经典算法,它通过利用图像中相似块的信息来减小噪声。以下是BM3D算法的MATLAB代码: ```matlab function [denoised_image] = bm3d(input_image, sigma) % 第一步:图像预处理 preprocessed_image = preprocessing(input_image); % 第二步:图片块分组 group_size = 8; % 定义块大小 [groups, num_blocks] = get_groups(preprocessed_image, group_size); % 第三步:相似块匹配 similar_blocks = find_similar_blocks(groups, num_blocks); % 第四步:3D变换 transformed_blocks = transform(similar_blocks, sigma); % 第五步:聚类和阈值 filtered_blocks = filter(transformed_blocks, sigma); % 第六步:逆变换 denoised_blocks = inverse_transform(filtered_blocks); % 第七步:聚合 denoised_image = aggregation(denoised_blocks); end function [preprocessed_image] = preprocessing(input_image) % 在此添加图像预处理的代码,例如灰度转换、亮度增强等 end function [groups, num_blocks] = get_groups(preprocessed_image, group_size) % 在此添加图像块分组的代码,返回块组和块的总数 end function [similar_blocks] = find_similar_blocks(groups, num_blocks) % 在此添加查找相似块的代码,返回相似块的结果 end function [transformed_blocks] = transform(similar_blocks, sigma) % 在此添加3D变换的代码,对相似块进行变换并返回结果 end function [filtered_blocks] = filter(transformed_blocks, sigma) % 在此添加聚类和阈值处理的代码,对变换后的块进行处理并返回结果 end function [denoised_blocks] = inverse_transform(filtered_blocks) % 在此添加逆变换的代码,将处理后的块进行逆变换 end function [denoised_image] = aggregation(denoised_blocks) % 在此添加聚合的代码,将处理后的块进行聚合并还原成图像 end ``` 以上是BM3D算法的主要步骤,并且提供了每个步骤的函数框架。具体的实现细节需要根据具体算法进行编写,可以根据BM3D算法的详细论文或参考其他实现的代码进行具体实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值