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 × 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 > &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 > &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)暂停更 |