难度:中等
题目要求:
给定一个可包含重复数字的序列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]]
题解:
用 n n n 表示数组 n u m s nums nums 的长度,创建列表 t e m p temp temp 用于存储当前排列,生成排列的做法是将数组 n u m s nums nums 中的每个元素按照特定顺序依次加入 t e m p temp temp,当 t e m p temp temp 中的元素个数等于 n n n 时,即可得到一个排列
在排列后的数组 n u m s nums nums 中遍历到下标 i i i 时,一下两种情况不应将 n u m s [ i ] nums[i] nums[i] 加入当前排列
- 如果 n u m s [ i ] nums[i] nums[i] 已经加入当前数列,则不能多次加入当前排列
- 如果当 i > 0 i>0 i>0 时, n u m s [ i ] = n u m s [ i − 1 ] nums[i]=nums[i-1] nums[i]=nums[i−1] 且 n u m s [ i − 1 ] nums[i-1] nums[i−1] 未加入当前数列,则不能将 n u m s [ i ] nums[i] nums[i] 加入当前数列
其余情况下,执行如下操作
- 将 n u m s [ i ] nums[i] nums[i] 加入当前排列,并将该元素的状态更新为已经加入当前排列,然后继续回溯
- 将当前排列末尾元素(即 n u m s [ i ] nums[i] nums[i] )移除,并将该元素的状态更新为未加入当前排列,恢复到原始状态
遍历结束之后,即可得到数组 n u m s nums nums 的无重复全排列
想法代码
public class Solution
{
IList> permutations = new List>();
IList temp = new List();
int[] nums;
int n;
bool[] visited;
public static void Main(string[] args)
{
int[] nums = { 1, 1, 2 };
Solution solution = new Solution();
IList> res = solution.PermuteUnique(nums);
foreach (var a in res)
{
foreach (var b in a)
{
Console.Write(b + " ");
}
Console.WriteLine();
}
}
public IList> PermuteUnique(int[] nums)
{
Array.Sort(nums);
this.nums = nums;
this.n = nums.Length;
this.visited = new bool[n];
Backtrack(0);
return permutations;
}
public void Backtrack(int index)
{
if (index == n)
{
permutations.Add(new List(temp));
}
else
{
for (int i = 0; i < n; i++)
{
if (visited[i] || (i > 0 && nums[i] == nums[i - 1] && !visited[i - 1]))
{
continue;
}
temp.Add(nums[i]);
visited[i] = true;
Backtrack(index + 1);
temp.RemoveAt(index);
visited[i] = false;
}
}
}
}
难度:中等
题目要求:
给定一个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]]
题解:
将最外圈进行旋转,左上转右上,以此类推,之后再旋转内圈即可
想法代码:
public class Solution
{
public static void Main(string[] args)
{
Solution solution = new Solution();
int[][] matrix = new int[3][]
{
new int[] { 1, 2, 3 },
new int[] { 4, 5, 6 },
new int[] { 7, 8, 9 },
};
solution.Rotate(matrix);
foreach (var i in matrix)
{
foreach (var j in i)
{
Console.Write(j + " ");
}
Console.WriteLine();
}
}
public void Rotate(int[][] matrix)
{
if (matrix[0].Length == 1) return;
int r = 0, c = matrix.Length - 1;
for (int i = 0; i < matrix.Length / 2; i++)
{
for (int j = 0; j < (c - r); j++)
{
int temp = matrix[r][r + j];
matrix[r][r + j] = matrix[c - j][r];
matrix[c - j][r] = matrix[c][c - j];
matrix[c][c - j] = matrix[r + j][c];
matrix[r + j][c] = temp;
}
r++;
c--;
}
}
}