RUST 刷题 数组篇

341 阅读2分钟

1.  (27) 移除元素

给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素.

  • 空间消耗必须为 O(1), 所以不允许使用辅助空间
  • 原地移除

思考: 主要还是使用 双指针的方法来解决.

1.快慢指针

impl Solution {
    pub fn remove_element(nums: &mut Vec<i32>, val: i32) -> i32 {
    let mut number = 0;
    for i in 0..nums.len() {
        if val != nums[i] {
            nums[number] = nums[i];
            number = number + 1;
        }
    }
    number as i32
    }
}
  1. 左右双指针
impl Solution {
    pub fn remove_element(nums: &mut Vec<i32>, val: i32) -> i32 {
        let mut len = nums.len();
        let mut idx = 0;

        while idx < len {
            if nums[idx] == val {
                nums[idx] = nums[len - 1];
                len -= 1;
                if len == 0 {
                    break;
                }
            } else {
                idx += 1;
            }
        }
        len as i32
    }
}

这存在几个点

我的想法是向量是不可变的(向量的数据类型和大小永远不会改变),但向量的内容应该是对整数的可变引用。或者它们应该是整数本身的实际值(而不是引用)?

引用(&'a T&'a mut T)只能引用另一个值拥有的值。引用不能拥有它们的引用对象。

可变向量与具有可变引用的不可变向量 待了解

2. [26] 删除有序数组中的重复项

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

实现 还是参考快慢指针, 唯一要注意的是, 这里的快慢指针不是在同一个端点开始的, 这里和上面一道题是不一样的.

impl Solution {
    pub fn remove_duplicates(nums: &mut Vec<i32>) -> i32 {
        if nums.len() < 1 {
            return 0;
        }
        let mut number = 1;
        for i in 1..nums.len() {
            if nums[number - 1] != nums[i] {
                number += 1;
                nums[number - 1] = nums[i];
            }
        }
        number as i32
    }
}

3. [59] 螺旋矩阵 II

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix。

基本上是实现一个搜索, 注意数组边界上的一些计算.

image.png

// 1, 0  -> down
// -1, 0 -> up;
// 0, 1 -> right;
// 0, -1 -> left;

当来做 7 这个位置上时, rust 不允许 数组索引值为负数, 所以 使用 l < 1 或 r < 1 来判断是否需要转向了

pub fn generate_matrix(n: i32) -> Vec<Vec<i32>> {
    let n = n as usize;
    let mut start = (0, 0);
    let mut out = vec![vec![-1; n]; n];
    let mut vector = (0, 1);

    // 1, 0  -> down
    // -1, 0 -> up;
    // 0, 1 -> right;
    // 0, -1 -> left;

    for em in 0..(n * n) {
        let (l, r) = start;
        out[l][r] = em as i32 + 1;

        match vector {
            (0, 1) => {
                if r + 1 >= n || out[l][r + 1] > 0 {
                    vector = (1, 0)
                }
            }

            (1, 0) => {
                if l + 1 >= n || out[l + 1][r] > 0 {
                    vector = (0, -1)
                }
            }

            (0, -1) => {
                if r as i32 - 1 < 0 || out[l][r - 1] > 0 {
                    vector = (-1, 0)
                }
            }
            (-1, 0) => {
                if l as i32 - 1 < 1 || out[l - 1][r] > 0 {
                    vector = (0, 1)
                }
            }

            _ => (),
        }

        start = (
            (start.0 as i32 + vector.0) as usize,
            (start.1 as i32 + vector.1) as usize,
        );
    }
    out
}