如何修复使用HashMap <i32,PriorityQueue <i32,i32 >>对角排序矩阵的代码?

时间:2020-01-27 04:47:44

标签: rust

这是针对此编程问题(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
}

2 个答案:

答案 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
}
相关问题