给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素。
请注意,它是排序后的第k小元素,而不是第k个元素。
示例:
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],
k = 8,
返回 13。
说明:
你可以假设 k 的值永远是有效的, 1 ≤ k ≤ n2 。
第一行为k的值和矩阵的n的值
后续为n*n矩阵的数字,以空格分割
矩阵中第k小的元素
8 3 1 5 9 10 11 13 12 13 15
13
如果笔试过程中碰到这个题,又没有数据量和时间限制,肯定怎么方便怎么来,直接sort输出3分钟结束战斗;但是刷题时碰到这种特殊的状况的数据,可以往深了想一想,练一练自己的代码能力;下面我提供两个都AC了的方法供大家参考
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int k = sc.nextInt(),n = sc.nextInt();
int data[][] = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
data[i][j] = sc.nextInt();
}
}
System.out.println(findKthNum(data, k));
//System.out.println(findKthNum1(data, k));
}
//方法1,二分套二分,时间复杂度O(n*logn*logn)
public static int findKthNum(int[][] matrix, int k) {
int row = matrix.length;
int col = matrix[0].length;
int low = matrix[0][0];
int high = matrix[row - 1][col - 1];
int mid = 0;
int count = 0;
while (low <= high) {
count = 0;
mid = low + ((high - low) >> 1);
for (int[] item : matrix) {
count += binarySearchCount(item, mid);
}
if (count < k) {
low = mid + 1;
} else {
high = mid - 1;
}
}
//返回的low表示满足count >= k的最小的数,这个数就是要找的第k个数
return low;
}
public static int binarySearchCount(int[] data, int k) {
int begin = 0, end = data.length - 1;
int mid = 0;
while (begin <= end) {
mid = begin + ((end - begin) >> 1);
if (data[mid] <= k) { //这里要加上等于k的
begin = mid + 1;
} else {
end = mid - 1;
}
}
//全大于、全小于k都是begin,正好对应上了
//这里返回的begin表示<=k的数的个数
return begin;
}
//方法2,快排思想,把二维压成1维,用partion来找第k大的数,复杂度O(n^2),对比还是第一种方法复杂度低一些
//但是如果用排序了,对n^2的数据排序复杂度最小为O(n^2*log(n^2))
public static int findKthNum1(int[][] matrix, int k) {
int row = matrix.length;
int col = matrix[0].length;
int[] arr = new int[row * col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
arr[i * col + j] = matrix[i][j];
}
}
int begin = 0, end = arr.length - 1;
int pos;
while (begin <= end) {
pos = partition(arr, begin, end);
if (pos == k - 1) {
return arr[pos];
} else if (pos > k - 1) {
end = pos - 1;
} else {
begin = pos + 1;
}
}
return 0;
}
public static int partition(int[] arr, int begin, int end) {
int temp = arr[begin];
while (begin < end) {
while (begin < end && arr[end] >= temp) {
end--;
}
swap(arr,begin,end);
while (begin < end && arr[begin] < temp) {
begin++;
}
swap(arr,begin,end);
}
return begin;
}
public static void swap(int[]arr,int i,int j){
if (arr == null || i >= arr.length || j >= arr.length || i < 0 || j < 0) {
return;
}
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
int k, n;
int val;
cin >> k >> n;
vector<int> vec;
for(int i = 0; i < n; ++i){
for(int j = 0; j < n; ++j){
cin >> val;
vec.push_back(val);
}
}
sort(vec.begin(),vec.end());
cout << vec[k - 1] << endl;
return 0;
} import java.util.Arrays;
import java.util.Scanner;
public class Main {
/**
* 运行时间:64ms
*
* 占用内存:10520k
* */
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int k = scanner.nextInt();
int n = scanner.nextInt();
int[] record = new int[n * n];
for (int i = 0; i < n * n; i++) {
record[i]=scanner.nextInt();
}
Arrays.sort(record);
System.out.println(record[k-1]);
}
}
#include<bits/stdc++.h>
using namespace std;
int main() {
int k, n;
while (cin >> k >> n) {
int cnt = 0, t;
multiset<int> s;
for (int i = 0; i < n*n; i++) {
cin >> t;
s.insert(t);
}
for (auto i : s) {
if (cnt < k-1)cnt++;
else{
cout << i << endl;
break;
}
}
}
return 0;
}
/*
时间复杂度没控制,变成了排序题
*/
#include<bits/stdc++.h>
using namespace std;
#define N 10000
int main()
{
// freopen("input.txt", "r", stdin);
int k, n;
cin >> k >> n;
vector<int> a(n * n);
for(int i = 0; i < n * n; i++) {
cin >> a[i];
}
sort(a.begin(), a.end());
cout << a[k - 1] << endl;
return 0;
}
//获取arr[][]略
int[][] location=new int[n+1][n+1];
List<Integer> list=new LinkedList<>();
list.add(0);
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {
int start=location[i+1][j]>location[i][j+1]?location[i+1][j]:location[i][j+1];
while(list.get(start)!=0&&list.get(start)<arr[i][j])
start++;
location[i+1][j+1]=start;
list.add(start, arr[i][j]);
}
}System.out.println(list.get(target-1)); const readline = require('readline')
const rl = readline.createInterface({
input: process.stdin,
ouput: process.stdout
})
let inArr = []
let n
rl.on('line',line=>{
if(!line) return
inArr.push(line)
if(inArr.length === 1){
k = +inArr[0].split(' ')[0]
n = +inArr[0].split(' ')[1]
}
if(inArr.length === n+1){
let res = []
let ans
for (let i = 0; i < n; i++) {
res[i] = inArr[i+1].split(' ').map(e => +e)
}
res = [].concat(...res).sort((a,b) => a-b)
ans = res[k-1]
console.log(ans)
}
}) #include<bits/stdc++.h>
using namespace std;
int main() {
int k, n;
cin >> k >> n;
vector<int> f(n*n);
for (int i=0; i<n; ++i) {
for (int j=0; j<n; ++j) {
cin >> f[i*n+j];
}
}
sort(f.begin(), f.end());
cout << f[k-1] <<endl;
return 0;
} #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(void) {
int k, n, x;
cin >> k >> n;
vector<int> nums;
for (int i = 0; i < n * n; ++i) {
cin >> x;
nums.emplace_back(x);
}
sort(begin(nums), end(nums));
cout << nums[k - 1] << endl;
return 0;
} public static void solve(int[][] arr,int k) {
int[] pos=new int[arr.length];
int tmp=0;
for(int i=0;i<k;i++) {
tmp=Integer.MAX_VALUE;
int index=0;
for(int j=0;j<arr.length;j++) {
if(pos[j]<arr.length&&arr[j][pos[j]]<tmp) {
tmp=arr[j][pos[j]];
index=j;
}
}
pos[index]++;
}
System.out.println(tmp);
}