| | 1 | 2 | 3| 5 |
|–|–|–|–|–|–|
|1 | - | 1/2 | 1/3 | 1/5 |
| 2 | | - | 2/3 | 2/5 |
| 3 | | | - | 3/5 |
| 5 | | | | - |
把右上角放进去,向左和向下都是变小
广度优先搜索
每次把下面和左面的位置放到优先队列里面
取到第k个就行了
注意标记是否访问过
避免重复入队
class Solution {
public:
struct pos{
int x;
int y;
};
vector<int> kthSmallestPrimeFraction(vector<int>& a, int k) {
auto cmp = [&](pos m,pos n){
// m.x/m.y>n.x/n.y;
return a[m.x]*a[n.y]>a[n.x]*a[m.y];
};
priority_queue<pos,vector<pos>,decltype(cmp)>qu(cmp);
int x = 0;
int y = a.size()-1;
qu.push(pos{x,y});
int i=0;
int n = a.size();
auto v = vector<vector<bool>>(n,vector<bool>(n,0));
v[x][y] =1;
while(!qu.empty()){
auto tp = qu.top();
qu.pop();
int qx = tp.x;
int qy = tp.y;
if(++i == k){
return {a[qx],a[qy]};
}
if( qx+1<n && qx+1<qy && v[qx+1][qy]==0){
qu.push(pos{qx+1,qy});
v[qx+1][qy]=1;
}
if( qy-1>=0 && qx < qy-1 && v[qx][qy-1]==0){
qu.push(pos{qx,qy-1});
v[qx][qy-1]=1;
}
}
return {0,0};
}
};
其实没列都是从上到下递增的
那么其实就是k路归并了
找到第k个就行了
每次只需要向下拓展就可以了
class Solution {
public:
struct pos{
int x;
int y;
};
vector<int> kthSmallestPrimeFraction(vector<int>& a, int k) {
auto cmp = [&](pos m,pos n){
// m.x/m.y>n.x/n.y;
return a[m.x]*a[n.y]>a[n.x]*a[m.y];
};
priority_queue<pos,vector<pos>,decltype(cmp)>qu(cmp);
int x = 0;
int y = a.size()-1;
int i=0;
int n = a.size();
for(int i=1;i<n;++i){
qu.push(pos{0,i});
}
for(int i=0;i+1<k;++i){
auto tp = qu.top();
qu.pop();
int qx = tp.x;
int qy = tp.y;
if(qx+1<qy){
qu.push(pos{qx+1,qy});
}
}
auto tp = qu.top();
return {a[tp.x],a[tp.y]};
}
};