Rust每日一练(Leetday0016) 全排列I\II、旋转图像

news2024/11/19 15:24:23

目录

46. 全排列 Permutations  🌟🌟

47. 全排列 II Permutations II  🌟🌟

48. 旋转图像 Rotate Image  🌟🌟

🌟 每日一练刷题专栏 🌟

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏


46. 全排列 Permutations

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例 2:

输入:nums = [0,1]
输出:[[0,1],[1,0]]

示例 3:

输入:nums = [1]
输出:[[1]]

提示:

  • 1 <= nums.length <= 6
  • -10 <= nums[i] <= 10
  • nums 中的所有整数 互不相同

代码: 回溯法

fn permute(nums: Vec<i32>) -> Vec<Vec<i32>> {
    let mut res: Vec<Vec<i32>> = Vec::new();
    if nums.len() == 0 {
        return res;
    }
    let mut used: Vec<bool> = vec![false; nums.len()];
    fn backtrack(path: &mut Vec<i32>, res: &mut Vec<Vec<i32>>, nums: &Vec<i32>, used: &mut Vec<bool>) {
        if path.len() == nums.len() {
            let tmp = path.clone();
            res.push(tmp);
            return;
        }
        for i in 0..nums.len() {
            if !used[i] {
                used[i] = true;
                path.push(nums[i]);
                backtrack(path, res, nums, used);
                path.pop();
                used[i] = false;
            }
        }
    }
    backtrack(&mut Vec::new(), &mut res, &nums, &mut used);
    return res;
}

fn main() {
    println!("{:?}", permute(vec![1, 2, 3]));
    println!("{:?}", permute(vec![0, 1]));
    println!("{:?}", permute(vec![1]));
}

输出:

[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
[[0, 1], [1, 0]]
[[1]]

代码2: 字典序法

fn permute(nums: &mut [i32]) -> Vec<Vec<i32>> {
    let mut res = vec![];
    if nums.len() == 1 {
            res.push(nums.to_vec());
            return res;
        }
    nums.sort();
    loop {
        let tmp = nums.to_vec();
        res.push(tmp);
        let (mut i, mut j) = (nums.len() - 2, nums.len() - 1);
        while i > 0 && nums[i] >= nums[i + 1] {
            i -= 1;
        }
        if i == 0 && nums[i] >= nums[i + 1] {
            break;
        }
        while nums[j] <= nums[i] {
            j -= 1;
        }
        nums.swap(i, j);
        nums[i + 1..].reverse();
    }
    res
}

fn main() {
    let mut nums = [1, 2, 3];
    println!("{:?}", permute(&mut nums));
    let mut nums = [0, 1];
    println!("{:?}", permute(&mut nums));
    let mut nums = [1];
    println!("{:?}", permute(&mut nums));
}

代码3: DFS

fn permute(nums: Vec<i32>) -> Vec<Vec<i32>> {
    fn dfs(nums: &Vec<i32>, index: usize, p: &mut Vec<i32>, res: &mut Vec<Vec<i32>>, used: &mut Vec<bool>) {
        if index == nums.len() {
            let temp = p.clone();
            res.push(temp);
            return;
        }
        for i in 0..nums.len() {
            if !used[i] {
                used[i] = true;
                p.push(nums[i]);
                dfs(nums, index + 1, p, res, used);
                p.pop();
                used[i] = false;
            }
        }
    }
    if nums.len() == 0 {
        return vec![];
    }
    let mut used: Vec<bool> = vec![false; nums.len()];
    let mut p: Vec<i32> = vec![];
    let mut res: Vec<Vec<i32>> = vec![];
    dfs(&nums, 0, &mut p, &mut res, &mut used);
    return res;
}

fn main() {
    println!("{:?}", permute(vec![1, 2, 3]));
    println!("{:?}", permute(vec![0, 1]));
    println!("{:?}", permute(vec![1]));
}

47. 全排列 II Permutations II

给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

示例 1:

输入:nums = [1,1,2]
输出:
[[1,1,2],
 [1,2,1],
 [2,1,1]]

示例 2:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

提示:

  • 1 <= nums.length <= 8
  • -10 <= nums[i] <= 10

代码1:  回溯法

fn permute_unique(nums: Vec<i32>) -> Vec<Vec<i32>> {
    fn backtrack(path: &mut Vec<i32>, res: &mut Vec<Vec<i32>>, nums: &Vec<i32>, used: &mut Vec<bool>) {
        if path.len() == nums.len() {
            let tmp = path.clone();
            res.push(tmp);
            return;
        }
        for i in 0..nums.len() {
            if used[i] || (i > 0 && !used[i - 1] && nums[i] == nums[i - 1]) {
                continue;
            }
            used[i] = true;
            path.push(nums[i]);
            backtrack(path, res, nums, used);
            path.pop();
            used[i] = false;
        }
    }
    let mut nums_copy = nums.clone();
    nums_copy.sort();
    let mut used: Vec<bool> = vec![false; nums.len()];
    let mut path: Vec<i32> = vec![];
    let mut res: Vec<Vec<i32>> = vec![];
    backtrack(&mut path, &mut res, &nums_copy, &mut used);
    return res;
}
fn main() {
    println!("{:?}", permute_unique(vec![1, 1, 2]));
    println!("{:?}", permute_unique(vec![1, 2, 3]));
}

输出:

[[1, 1, 2], [1, 2, 1], [2, 1, 1]]
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]

代码2:  字典序法

fn permute_unique(nums: &mut [i32]) -> Vec<Vec<i32>> {
    let mut res = vec![];
    if nums.is_empty() {
        return res;
    }
    nums.sort();
    let len = nums.len();
    let (mut i, mut j) = (len - 2, len - 1);
    loop {
        let tmp = nums.to_vec();
        res.push(tmp);
        while i > 0 && nums[i] >= nums[i + 1] {
            i -= 1;
        }
        if i == 0 && nums[i] >= nums[i + 1] {
            break;
        }
        while j > 0 && nums[j] <= nums[i] {
            j -= 1;
        }
        if nums[j] == nums[i] && j > i + 1 {
            continue;
        }
        nums.swap(i, j);
        nums[i + 1..].reverse();
        if i == 0 && j == 1 {
            break;
        }
        i = len - 2;
        j = len - 1;
    }
    res
}

fn main() {
    let mut nums = [1, 1, 2];
    println!("{:?}", permute_unique(&mut nums));
    let mut nums = [1, 2, 3];
    println!("{:?}", permute_unique(&mut nums));
}

 代码3:  DFS

fn permute_unique(nums: &mut [i32]) -> Vec<Vec<i32>> {
    let mut res = vec![];
    if nums.is_empty() {
        return res;
    }
    let mut used = vec![false; nums.len()];
    let mut p = vec![];
    nums.sort();
    dfs(nums, 0, &mut p, &mut res, &mut used);
    res
}

fn dfs(nums: &[i32], index: usize, p: &mut Vec<i32>, res: &mut Vec<Vec<i32>>, used: &mut [bool]) {
    if index == nums.len() {
        res.push(p.clone());
        return;
    }
    for i in 0..nums.len() {
        if !used[i] {
            if i > 0 && nums[i] == nums[i - 1] && !used[i - 1] {
                continue;
            }
            used[i] = true;
            p.push(nums[i]);
            dfs(nums, index + 1, p, res, used);
            p.pop();
            used[i] = false;
        }
    }
}

fn main() {
    let mut nums = [1, 1, 2];
    println!("{:?}", permute_unique(&mut nums));
    let mut nums = [1, 2, 3];
    println!("{:?}", permute_unique(&mut nums));
}
fn permute_unique(nums: Vec<i32>) -> Vec<Vec<i32>> {
    fn dfs(nums: &[i32], index: usize, p: &mut Vec<i32>, res: &mut Vec<Vec<i32>>, used: &mut [bool]) {
        if index == nums.len() {
            res.push(p.clone());
            return;
        }
        for i in 0..nums.len() {
            if !used[i] {
                if i > 0 && nums[i] == nums[i - 1] && !used[i - 1] {
                    continue;
                }
                used[i] = true;
                p.push(nums[i]);
                dfs(nums, index + 1, p, res, used);
                p.pop();
                used[i] = false;
            }
        }
    }
    if nums.is_empty() {
        return vec![];
    }
    let mut nums_copy = nums.clone();
    nums_copy.sort();
    let mut res: Vec<Vec<i32>> = vec![];
    let mut used = vec![false; nums.len()];
    dfs(&nums_copy, 0, &mut vec![], &mut res, &mut used);
    res
}

fn main() {
    println!("{:?}", permute_unique(vec![1, 1, 2]));
    println!("{:?}", permute_unique(vec![1, 2, 3]));
}

48. 旋转图像 Rotate Image

给定一个 × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

你必须在
 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

示例 1:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]

示例 2:

输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]

提示:

  • n == matrix.length == matrix[i].length
  • 1 <= n <= 20
  • -1000 <= matrix[i][j] <= 1000

代码1: 转置加翻转

先转置矩阵,然后翻转每一行即可得到顺时针旋转 90 度后的矩阵。

fn rotate(matrix: &mut Vec<Vec<i32>>) {
    let n = matrix.len();
    // 转置矩阵
    for i in 0..n {
        for j in i..n {
            let temp = matrix[i][j];
            matrix[i][j] = matrix[j][i];
            matrix[j][i] = temp;
        }
    }
    // 翻转每一行
    for i in 0..n {
        for j in 0..n / 2 {
            let temp = matrix[i][j];
            matrix[i][j] = matrix[i][n - j - 1];
            matrix[i][n - j - 1] = temp;
        }
    }
}

fn main() {
    let mut matrix = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
    rotate(&mut matrix);
    println!("{:?}", matrix);
    let mut matrix = vec![vec![5, 1, 9, 11], vec![2, 4, 8, 10], vec![13, 3, 6, 7], vec![15, 14, 12, 16]];
    rotate(&mut matrix);
    println!("{:?}", matrix);
}

输出:

[[7, 4, 1], [8, 5, 2], [9, 6, 3]]
[[15, 13, 2, 5], [14, 3, 4, 1], [12, 6, 8, 9], [16, 7, 10, 11]]

代码2: 分块翻转

将矩阵分成四个部分,并将每个部分按顺时针旋转 90 度。

fn rotate(matrix: &mut Vec<Vec<i32>>) {
    let n = matrix.len();
    // 转置矩阵
    for i in 0..n {
        for j in i..n {
            let temp = matrix[i][j];
            matrix[i][j] = matrix[j][i];
            matrix[j][i] = temp;
        }
    }
    // 翻转每一行
    for i in 0..n {
        for j in 0..n / 2 {
            let temp = matrix[i][j];
            matrix[i][j] = matrix[i][n - j - 1];
            matrix[i][n - j - 1] = temp;
        }
    }
}

fn main() {
    let mut matrix = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
    rotate(&mut matrix);
    println!("{:?}", matrix);
    let mut matrix = vec![vec![5, 1, 9, 11], vec![2, 4, 8, 10], vec![13, 3, 6, 7], vec![15, 14, 12, 16]];
    rotate(&mut matrix);
    println!("{:?}", matrix);
}

代码3: 对角线变换+水平翻转

将矩阵分成四个部分,并将每个部分按顺时针旋转 90 度。

fn rotate(matrix: &mut Vec<Vec<i32>>) {
    let row = matrix.len();
    if row <= 0 {
        return;
    }
    let column = matrix[0].len();
    // 对角线变换
    for i in 0..row {
        for j in i + 1..column {
            let temp = matrix[i][j];
            matrix[i][j] = matrix[j][i];
            matrix[j][i] = temp;
        }
    }
    // 竖直轴对称翻转
    let half_column = column / 2;
    for i in 0..row {
        for j in 0..half_column {
            let temp = matrix[i][j];
            matrix[i][j] = matrix[i][column - j - 1];
            matrix[i][column - j - 1] = temp;
        }
    }
}

fn main() {
    let mut matrix = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
    rotate(&mut matrix);
    println!("{:?}", matrix);
    let mut matrix = vec![vec![5, 1, 9, 11], vec![2, 4, 8, 10], vec![13, 3, 6, 7], vec![15, 14, 12, 16]];
    rotate(&mut matrix);
    println!("{:?}", matrix);
}

翻转+旋转原理C代码 

/*
* clockwise rotate 顺时针旋转
* first reverse up to down, then swap the symmetry
* 1 2 3      7 8 9      7 4 1
* 4 5 6 => 4 5 6 => 8 5 2
* 7 8 9      1 2 3      9 6 3
*/
void rotate(vector<vector<int> > &matrix) {
    reverse(matrix.begin(), matrix.end());
    for (int i = 0; i < matrix.size(); ++i) {
        for (int j = i + 1; j < matrix[i].size(); ++j)
            swap(matrix[i][j], matrix[j][i]);
    }
}
/*
* anticlockwise rotate 逆时针旋转
* first reverse left to right, then swap the symmetry
* 1 2 3      3 2 1      3 6 9
* 4 5 6 => 6 5 4 => 2 5 8
* 7 8 9      9 8 7      1 4 7
*/
void anti_rotate(vector<vector<int> > &matrix) {
    for (auto vi : matrix) reverse(vi.begin(), vi.end());
        for (int i = 0; i < matrix.size(); ++i) {
            for (int j = i + 1; j < matrix[i].size(); ++j)
                swap(matrix[i][j], matrix[j][i]);
        }
}


🌟 每日一练刷题专栏 🌟

持续,努力奋斗做强刷题搬运工!

👍 点赞,你的认可是我坚持的动力! 

🌟 收藏,你的青睐是我努力的方向! 

评论,你的意见是我进步的财富!  

 主页:https://hannyang.blog.csdn.net/

Rust每日一练 专栏

(2023.5.16~)更新中...

Golang每日一练 专栏

(2023.3.11~)更新中...

Python每日一练 专栏

(2023.2.18~2023.5.18)暂停更

C/C++每日一练 专栏

(2023.2.18~2023.5.18)暂停更

Java每日一练 专栏

(2023.3.11~2023.5.18)暂停更

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/591692.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Golang每日一练(leetDay0082) 用队列实现栈、用栈实现队列

目录 225. 用队列实现栈 Implement Stack Using Queues &#x1f31f; 232. 用栈实现队列 Implement Queue Using Stacks &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust每日一练 专栏 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 …

C#,码海拾贝(29)——求解“大型稀疏方程组”的“全选主元高斯-约去消去法”之C#源代码,《C#数值计算算法编程》源代码升级改进版

大型稀疏矩阵线性化方程组的数值求解问题 广泛存在于工程实践尤其是计算机仿真领域 如水力管网计算&#xff0c;电力系统的大型导纳矩阵计算&#xff0c;高阶偏微分方程的数值求解&#xff0c;以及铸件充型过程与凝固过程的数值模拟等。 经常出现在科学和工程计算中, 因此寻找稀…

chatgpt赋能python:Python中的平均值及其计算方式

Python中的平均值及其计算方式 Python是广泛使用的编程语言之一&#xff0c;它拥有强大而且易于使用的数据处理和分析功能。在数据分析领域&#xff0c;计算平均值是非常常见的操作之一。Python中有多种方法可以计算平均值&#xff0c;包括使用内置的函数和使用第三方库。本文…

MySQL数据库 1.概述

数据库相关概念&#xff1a; 数据库(Database)&#xff1a;数据库是指一组有组织的数据的集合&#xff0c;通过计算机程序进行管理和访问。数据库管理系统&#xff1a;操纵和管理数据库的大型软件SQL&#xff1a;操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型数…

Linux之模拟shell命令行解释器

文章目录 前言一、输出提示符1.实际2.模拟 二、输入指令、获取指令1.实际2.模拟 三、fork创建子进程四、内建命令五、代码实现总结 前言 本文是基于前面介绍过的关于进程创建、进程终止、进程等待、进程替换等知识&#xff0c;尝试做的一个简单的shell命令解释器。 一、输出提…

OpenCV实战(25)——3D场景重建

OpenCV实战&#xff08;25&#xff09;——3D场景重建 0. 前言1. 重建 3D 场景1.1 3D 场景点重建1.2 算法原理 2. 分解单应性3. 光束平差法4. 完整代码小结系列链接 0. 前言 在《相机姿态估计》一节中&#xff0c;我们学习了如何在校准相机时恢复观察 3D 场景的相机的位置。算…

TypeScript的10个缺点

文章目录 1. 语法繁琐2. 难以集成到一些工作流程3. 学习成本高4. 代码量多5. 编译时间长6. 在小型项目中无必要性7. 可读性降低8. 抽象层次增加9. 缺少类型定义10. 生态系统 1. 语法繁琐 TypeScript 的类型注解、泛型等语法增加了代码的复杂度和学习难度&#xff0c;对小型项目…

LC-1130. 叶值的最小代价生成树(贪心、区间DP、单调栈)

1130. 叶值的最小代价生成树 难度中等272 给你一个正整数数组 arr&#xff0c;考虑所有满足以下条件的二叉树&#xff1a; 每个节点都有 0 个或是 2 个子节点。数组 arr 中的值与树的中序遍历中每个叶节点的值一一对应。每个非叶节点的值等于其左子树和右子树中叶节点的最大…

chatgpt赋能python:Python中的逆序操作

Python 中的逆序操作 在 Python 中&#xff0c;逆序&#xff08;reverse&#xff09;操作指的是将一个序列的元素顺序反转&#xff0c;也即将序列中最后一个元素变成第一个&#xff0c;倒数第二个元素变成第二个&#xff0c;以此类推。逆序有很多实际用途&#xff0c;比如根据…

基于C语言的平衡二叉树操作(包含完整代码)

平衡二叉树的定义: 为避免树的高度增长过快&#xff0c;降低二叉排序树的性能&#xff0c;规定在插入和删除二叉树结点时&#xff0c;要保证任意结点的左、右子树高度差的绝对值不超过1&#xff0c;将这样的二义树称为平衡二叉树AVL (Balanced Binary Tree),简称平衡树。 平衡…

【源码解析】流控框架Sentinel源码深度解析

前言 前面写了一篇Sentinel的源码解析&#xff0c;主要侧重点在于Sentinel流程的运转原理。流控框架Sentinel源码解析&#xff0c;侧重点在整个流程。该篇文章将对里面的细节做深入剖析。 统计数据 StatisticSlot用来统计节点访问次数 SpiOrder(-7000) public class Statis…

PCL 改进点云双边滤波算法

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 我们先来回顾一下之前该算法的计算过程,在二维图像领域中,双边滤波算法是通过考虑中心像素点到邻域像素点的距离(一边)以及像素亮度差值所确定的权重(另一边)来修正当前采样中心点的位置,从而达到平滑滤波效果。…

PHPMySQL基础(五):模拟登录后跳转+会话存储功能实现

PHP&MySQL基础&#xff08;一&#xff09;:创建数据库并通过PHP进行连接_长风沛雨的博客-CSDN博客 PHP&MySQL基础&#xff08;二&#xff09;:通过PHP对MySQL进行增、删、改、查_长风沛雨的博客-CSDN博客 PHP&MySQL基础&#xff08;三&#xff09;:处理查询SQL返…

一图看懂 tqdm 模块:一个可在循环和命令行中使用的快速、可扩展的进度条,资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 tqdm 模块&#xff1a;一个可在循环和命令行中使用的快速、可扩展的进度条&#xff0c;资料整理笔记&#xff08;大全&#xff09; &#x1f9ca;摘要&#x1f9ca;模块图&…

软考高级架构师笔记-5计算机网络

目录 1. 前言 & 考情分析2. 网络功能和分类2.1 通信技术3. OSI七层模型及协议3. 1 局域网和广域网协议3. 2 协议3. 3 交换技术、路由、传输介质4 IP地址5 网络存储技术6 其它考点8. 结语1. 前言 & 考情分析 前文回顾: 软考高级架构师笔记-1计算机硬件软考高级架构师笔…

chatgpt赋能python:Python中未定义变量的默认值

Python中未定义变量的默认值 在Python编程中&#xff0c;有时候我们会使用未经定义的变量。如果这些变量没有被定义&#xff0c;那么它们将没有任何值。在这篇文章中&#xff0c;我们将讨论Python中未定义变量默认值的问题&#xff0c;并深入研究为什么这些默认值如此重要。 …

华为OD机试真题B卷 Java 实现【寻找关键钥匙】,附详细解题思路

一、题目描述 小强正在参加《密室逃生》游戏&#xff0c;当前关卡要求找到符合给定 密码K&#xff08;升序的不重复小写字母组成&#xff09;的箱子&#xff0c;并给出箱子编号&#xff0c;箱子编号为1~N。 每个箱子中都有一个字符串s&#xff0c;字符串由大写字母&#xff0…

改进YOLOv5,利用HRNet高分辨率特征金字塔的全新物体检测突破

目录 一、介绍1、物体检测的背景与重要性2、HRNet和YOLOv5的概述&#xff08;1&#xff09;HRNet的概述&#xff08;2&#xff09;YOLOv5的概述 二、HRNet的架构1、HRNet的基本单元2、HRNet的高分辨率特征金字塔3、HRNet的体系结构4、HRNet的特点5、HRNet的局限性 三、YOLOv5的…

chatgpt赋能python:Python中转化为列表的详细介绍

Python中转化为列表的详细介绍 Python是一门高级编程语言&#xff0c;它使用起来简单易学&#xff0c;被广泛应用于大数据处理、科学计算、机器学习等领域。在Python编程中&#xff0c;列表是一种非常重要的数据结构&#xff0c;它允许我们存储和操作一组数据&#xff0c;并且…

jenkins —— pipeline基础语法与示例

一、Jenkins介绍 二、Jenkins Pipeline介绍 Jenkins Pipeline总体介绍 1.Pipeline 是Jenkins 2.X核心特性&#xff0c;帮助Jenkins实现从CI到CD与DevOps的转变 2.Pipeline 简而言之&#xff0c;就是一套运行于Jenkins上的工作流框架&#xff0c;将原本独立 运行于单个或者多个…