算法进修Day-24

算法进修Day-24

47. 全排列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]]

题解

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[i1] n u m s [ i − 1 ] nums[i-1] nums[i1] 未加入当前数列,则不能将 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;
            }
        }
    }
}

48. 旋转图像

难度:中等
题目要求:
给定一个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--;
        }
    }
}

你可能感兴趣的:(算法进修,算法,leetcode,c#)