给定一个 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); }