链接:5403. 有序矩阵中的第 k 个最小数组和
有一说一,题是好理解,但是真难做…最后 1 个多小时都在干这个题目,还是没能干出来…结果暴力就能过…真的…暴力出奇迹。
这个暴力不知道稳定不,在比赛时 cpp
貌似没过,java
可以,也都是听大佬讲的,自己想了一堆奇妙的方法,磕磕绊绊把自己绕进去了。
见题解大佬 Ikaruga【有序矩阵中的第 k 个最小数组和】抄作业。看了大佬的代码总是能学习几个新函数 。
二分 + dfs
应该是这道题很棒的解法了。
参见代码如下:
// 执行用时 :1376 ms, 在所有 C++ 提交中击败了100.00%的用户
// 内存消耗 :156.1 MB, 在所有 C++ 提交中击败了100.00%的用户
class Solution {
public:
int kthSmallest(vector<vector<int>>& mat, int k) {
vector<int> ans(mat[0]);
for (int i = 1; i < mat.size(); ++i) {
multiset<int> st;
for (int x : ans) {
for (int y : mat[i]) {
st.insert(x + y);
}
}
ans.assign(st.begin(), st.end());
ans.resize(min(k, (int)ans.size()));
}
return ans.back();
}
};
作者:newbie-19
链接:https://leetcode-cn.com/problems/find-the-kth-smallest-sum-of-a-matrix-with-sorted-rows/solution/er-fen-by-newbie-19-3/
来源:力扣(LeetCode)
class Solution {
public:
int kthSmallest(vector<vector<int>>& mat, int k) {
int m=mat.size(),n=mat[0].size();
multiset<int>s(mat[0].begin(),mat[0].end());
for(int i=1;i<m;i++){
multiset<int>temp;
for(int x : s){
for(int y : mat[i]){
temp.insert(x+y);
}
}
s.clear();
auto it=temp.begin();
for(int j=0;j<min(k,(int)temp.size());j++,it++){
s.insert(*it);
}
}
return *s.rbegin();
}
};
来自坑神的代码+思路…由于数据最大为 40 * 200 = 8000
故可选择暴力去做。坑神一开始想精细化的去 bfs
即在优先队列中仅保留 200 个理想状态即可,但是确实很麻烦就改道暴力了。
有一说一,代码没看太懂,bfs
学的菜…人被这个题整蒙了…
参考代码如下:
// 执行用时 :284 ms, 在所有 C++ 提交中击败了100.00%的用户
// 内存消耗 :13 MB, 在所有 C++ 提交中击败了100.00%的用户
const int INF = 1e9;
int n, m;
vector<vector<int>> mat;
struct Node {
int cur[41], sum = 0;
Node(){
sum = 0;
for (int i = 0; i < n; i++)
sum = sum + mat[i][cur[i] = 0];
}
Node getNext(int k){
Node ret;
for (int i = 0; i < n; i++) ret.cur[i] = cur[i];
ret.cur[k]++; ret.sum = 0;
for (int i = 0; i < n; i++) ret.sum += mat[i][ret.cur[i]];
return ret;
}
string i2s(int x){
string ret = "";
while(x){
ret += (char)(x % 10 + '0');
x /= 10;
}
return ret;
}
string getString(){
string ret = "";
for (int i = 0; i < n; i++)
ret += "#" + i2s(cur[i]);
return ret;
}
friend bool operator < (const Node &a, const Node &b){
return a.sum > b.sum;
}
};
set<string> hash_que;
priority_queue<Node> que;
class Solution {
public:
int kthSmallest(vector<vector<int>>& v, int k) {
mat = v; n = mat.size(); m = mat[0].size();
while(!que.empty()) que.pop();
que.push(Node()); hash_que.clear();
int cnt = 0;
while(!que.empty()){
Node x = que.top(); que.pop();
if (hash_que.insert(x.getString()).second){
++cnt;
if (cnt == k) return x.sum;
for (int i = 0; i < n; i++)
if (x.cur[i] + 1 < m) que.push(x.getNext(i));
}
}
return 0;
}
};
依旧见题解大佬 Ikaruga【有序矩阵中的第 k 个最小数组和】抄作业。
newbie大佬二分高赞答案
class Solution {
public:
int kthSmallest(vector<vector<int>>& mat, int k) {
int l = 0;
int r = 0;
for (int i = 0; i < mat.size(); i++) {
l += mat[i].front();
r += mat[i].back();
}
int base = l;
while (l < r) {
int mid = l + (r - l) / 2;
int cnt = 1;
dfs(mat, k, mid, 0, base, cnt);
if (cnt < k) {
l = mid + 1;
}
else {
r = mid;
}
}
return r;
}
void dfs(vector<vector<int>>& mat, int k, int maxSum, int idx, int sum, int& cnt) {
if (idx == mat.size()) return;
if (sum > maxSum || cnt > k) return;
dfs(mat, k, maxSum, idx + 1, sum, cnt);
for (int j = 1; j < mat[idx].size(); j++) {
int temp = sum + mat[idx][j] - mat[idx][0];
if (temp > maxSum) break;
cnt++;
dfs(mat, k, maxSum, idx + 1, temp, cnt);
}
}
};
作者:newbie-19
链接:https://leetcode-cn.com/problems/find-the-kth-smallest-sum-of-a-matrix-with-sorted-rows/solution/er-fen-by-newbie-19-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
vector<vector<int>>temp;
int m,n;
int kthSmallest(vector<vector<int>>& mat, int k) {
temp=mat;
m=mat.size(),n=mat[0].size();
int left=0,right=0;
for(int i=0;i<m;i++) left+=mat[i][0],right+=mat[i].back();
int init=left;
while(left<right){
int mid=(left+right)>>1;
int num=1;
dfs(mid,0,init,num,k);
if(num>=k) right=mid;
else left=mid+1;
}
return left;
}
void dfs(int mid,int index,int sum,int& num,int k){
if(sum>mid||index==m||num>k) return;
dfs(mid,index+1,sum,num,k);
for(int i=1;i<n;i++){
if(sum+temp[index][i]-temp[index][0]<=mid){
num++;
dfs(mid,index+1,sum+temp[index][i]-temp[index][0],num,k);
}else{
break;
}
}
}
};