这是针对此编程问题(LeetCode 1329. Sort the Matrix Diagonally)的c ++解决方案。
vector<vector<int>> diagonalSort(vector<vector<int>>& mat) {
int m = mat.size();
int n = mat[0].size();
map<int, priority_queue<int>> mq;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
mq[i - j].push(-mat[i][j]);
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
priority_queue<int>& q = mq[i - j];
mat[i][j] = -q.top();
q.pop();
}
}
return mat;
}
当我将此C ++代码转换为Rust时,遇到了一个我无法解决的问题。
use std::collections::HashMap;
use priority_queue::PriorityQueue;
fn diagonal_sort(mat: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
let mut mat = mat.clone();
let m = mat.len();
let n = mat[0].len();
let mut mq: HashMap<i32, PriorityQueue<i32, i32>> = HashMap::new();
println!("m {}, n {}", m, n);
for i in 0..mat.len() {
for j in 0..mat[0].len() {
mq.entry(i as i32 - j as i32).or_insert(PriorityQueue::new()).push(mat[i][j], mat[i][j]);
}
}
for i in 0..mat.len() {
for j in 0..mat[0].len() {
// Ideally, how do I pop here and use the results directly?
let res = mq[&(i as i32 - j as i32)].peek();
mat[i][j] = *(match res {
Some((x, _y)) => x,
None => &(-1),
});
// Or how do I pop from the priority queue here without peeking?
// mq[&(i as i32 - j as i32)].pop();
}
}
mat
}
答案 0 :(得分:2)
从这里优先队列中弹出而无需窥视:
let v = d.get_mut(&key).unwrap();
mat[i][j] = v.pop().unwrap().0;
结果(输出):
input:
9 8 7
6 5 4
3 2 1
output:
1 4 7
2 5 8
3 6 9
您可以使用std::cmp::Reverse
进行反向排序:
use std::cmp::Reverse;
use std::collections::BinaryHeap;
use std::collections::HashMap;
pub fn diagonal_sort(mat: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
let mut mat = mat.clone();
let mut mh: HashMap<i32, BinaryHeap<_>> = HashMap::new();
for i in 0..mat.len() {
for j in 0..mat[0].len() {
let key = i as i32 - j as i32;
mh.entry(key)
.or_insert(BinaryHeap::new())
.push(Reverse(mat[i][j]));
}
}
for i in 0..mat.len() {
for j in 0..mat[0].len() {
let key = i as i32 - j as i32;
let q = mh.get_mut(&key).unwrap();
match q.pop().unwrap() {
Reverse(v) => mat[i][j] = v,
}
}
}
mat
}
fn main() {
let m = vec![vec![9, 8, 7], vec![6, 5, 4], vec![3, 2, 1]];
show("input:", &m);
let s = diagonal_sort(m);
show("output:", &s);
}
fn show(s: &str, mat: &Vec<Vec<i32>>) {
println!("{}", s);
let m = mat.len();
let n = mat[0].len();
for i in 0..m {
for j in 0..n {
print!("{} ", mat[i][j]);
}
println!();
}
}
结果(输出):
input:
9 6 3
8 5 2
7 4 1
output:
1 2 3
4 5 6
7 8 9
尝试以下操作(针对对角不同元素):
use priority_queue::PriorityQueue;
use std::collections::HashMap;
fn diagonal_sort(mat: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
let mut d: HashMap<i32, PriorityQueue<i32, i32>> = HashMap::new();
let mut mat = mat.clone();
let m = mat.len();
let n = mat[0].len();
for i in 0..m {
for j in 0..n {
let key = i as i32 - j as i32;
let v = -mat[i][j];
d.entry(key).or_insert(PriorityQueue::new()).push(v, v);
}
}
for i in 0..m {
for j in 0..n {
let key = i as i32 - j as i32;
let v = d.get_mut(&key).unwrap();
mat[i][j] = -v.pop().unwrap().0;
}
}
mat
}
fn main() {
let m = vec![vec![9, 6, 3], vec![8, 5, 2], vec![7, 4, 1]];
show("input:", &m);
let s = diagonal_sort(m);
show("output:", &s);
}
fn show(s: &str, mat: &Vec<Vec<i32>>) {
println!("{}", s);
let m = mat.len();
let n = mat[0].len();
for i in 0..m {
for j in 0..n {
print!("{} ", mat[i][j]);
}
println!();
}
}
答案 1 :(得分:1)
我发现使用std :: collections :: BinaryHeap解决此问题实际上更好。
use std::collections::BinaryHeap;
use std::collections::HashMap;
pub fn main() {
let mat = vec![vec![3,3,1,1],vec![2,2,1,2],vec![1,1,1,2]];
let res = diagonal_sort(mat);
println!("{:?}", res);
}
pub fn diagonal_sort(mat: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
let mut mat = mat.clone();
let mut mh: HashMap<i32, BinaryHeap<i32>> = HashMap::new();
for i in 0..mat.len() {
for j in 0..mat[0].len() {
let key = i as i32 - j as i32;
mh.entry(key)
.or_insert(BinaryHeap::new())
.push(-mat[i][j]);
}
}
for i in 0..mat.len() {
for j in 0..mat[0].len() {
let key = i as i32 - j as i32;
let q = mh.get_mut(&key).unwrap();
mat[i][j] = -(q.pop().unwrap());
}
}
mat
}