算法进修Day-23

算法进修Day-23

45. 跳跃游戏2

难度:中等
题目要求:
给定一个长度为n0索引整数数组nums。初始位置为nums[0]

每个元素nums[i]表示从索引i向前跳转的最大长度。换句话说,如果你在nums[i]处,你可以跳转到任意nums[i + j]处:

  • 0 <= j <= nums[i]
  • i + j < n

返回到达nums[n -1]的最小跳跃次数。生成的测试用例可以到达nums[n -1]

示例1

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

示例2

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

题解

使用贪心算法计算到达下标 n − 1 n-1 n1 的最小跳跃次数

c u r r e n t J u m p s currentJumps currentJumps 表示当前跳跃次数,用 c u r r e n t M a x P o s i t i o n currentMaxPosition currentMaxPosition n e x t M a x P o s i t i o n nextMaxPosition nextMaxPosition 分别表示跳跃次数 c u r r e n t J u m p s currentJumps currentJumps 能够到达的最远距离和跳跃次数 c u r r e n t J u m p s + 1 currentJumps+1 currentJumps+1 可以到达的最远距离,初始时 c u r r e n t J u m p s = 0 , c u r r e n t M a x P o s i t i o n = 0 , n e x t M a x P o s i t i o n = 0 currentJumps=0,currentMaxPosition=0,nextMaxPosition=0 currentJumps=0currentMaxPosition=0nextMaxPosition=0

从左到右遍历数组 n u m s nums nums,对每个 0 ≤ i < n 0\leq i0i<n,执行如下操作:

  • 如果 i > c u r r e n t M a x P o s i t i o n i>currentMaxPosition i>currentMaxPosition,则下标 i i i 超出跳跃次数 c u r r e n t J u m p s currentJumps currentJumps 可以到达的下标,因此到达下标 i i i 的最小跳跃次数是 c u r r e n t J u m p s + 1 currentJumps+1 currentJumps+1,需要更新 c u r r e n t J u m p s currentJumps currentJumps c u r r e n t M a x P o s i t i o n currentMaxPosition currentMaxPosition 的值;将 c u r r e n t J u m p s currentJumps currentJumps 的值加1,将 c u r r e n t M a x P o s i t i o n currentMaxPosition currentMaxPosition 的值更新为 n e x t M a x P o s i t i o n nextMaxPosition nextMaxPosition。如果 i ≤ c u r r e n t M a x P o s i t i o n i\leq currentMaxPosition icurrentMaxPosition,则不执行更新操作
  • 从下标 i i i 可以到达的最大下标为 i + n u m s [ i ] i+nums[i] i+nums[i]。由于跳跃次数 c u r r e n t J u m p s currentJumps currentJumps 可以到达下标 i i i,因此跳跃次数 c u r r e n t J u m p s + 1 currentJumps+1 currentJumps+1 可以到达下标 i + n u m s [ i ] i+nums[i] i+nums[i],跳跃次数 c u r r e n t J u m p s + 1 currentJumps+1 currentJumps+1 可以到达的最大下标不小于 i + n u m s [ i ] i+nums[i] i+nums[i],用 i + n u m s [ i ] i+nums[i] i+nums[i]更新 n e x t M a x P o s i t i o n nextMaxPosition nextMaxPosition 的值

遍历结束之后, c u r r e n t J u m p s currentJumps currentJumps 即为到达下标 n − 1 n-1 n1 的最小跳跃次数

想法代码

class Solution
{
    public static void Main(String[] args)
    {
        int[] nums = { 2, 3, 1, 1, 4 };
        Solution solution = new Solution();
        int res = solution.Jump(nums);
        Console.WriteLine(res);
    }

    public int Jump(int[] nums)
    {
        int currentJumps = 0;
        int currentMaxPosition = 0;
        int nextMaxPosition = 0;
        int len = nums.Length;
        for (int i = 0; i < len; i++)
        {
            if (i > currentMaxPosition)
            {
                currentJumps++;
                currentMaxPosition = nextMaxPosition;
            }
            nextMaxPosition = Math.Max(nextMaxPosition, nums[i] + i);
        }
        return currentJumps;
    }
}

46. 全排列

难度:中等
题目要求:
给定一个不含重复数字的数组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]]

题解

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 u m s nums nums 的全排列,需要依次确定排列中的每个位置的元素,可以通过交换 t e m p temp temp 中的元素实现,对于 0 ≤ i n d e x < n 0\leq index0index<n,按照下标 i n d e x index index 从小到大的顺序依次确定每个 t e m p [ i n d e x ] temp[index] temp[index] 的值,即能得到一个排列

  • i n d e x = 0 index=0 index=0,可以将 t e m p [ 0 ] temp[0] temp[0] 和任意一个元素交换(包括和自身交换),经过一次交换之后即可确定当前排列中的 t e m p [ 0 ] temp[0] temp[0] 的值
  • i n d e x > 0 index>0 index>0,如果当前排列中 t e m p [ 0 ] temp[0] temp[0] t e m p [ i n d e x − 1 ] temp[index-1] temp[index1] 的值都已经确定,则可以将 t e m p [ i n d e x ] temp[index] temp[index] 和任意一个下标大于等于 i n d e x index index 的元素交换,经过一次交换之后即可确定当前排列中 t e m p [ i n d e x ] temp[index] temp[index] 的值

通过上述分析,可以利用回溯法,步骤如下:

  • 如果 i n d e x = n index=n index=n,则当前排列中的所有元素都已经确定,则将当前排列添加到结果列表中
  • 如果 i n d e x < n indexindex<n,则对于每一个 i n d e x ≤ i < n index\leq iindexi<n,执行如下操作:
    • t e m p [ i n d e x ] temp[index] temp[index] t e m p [ i ] temp[i] temp[i] 的值交换,然后将 i n d e x + 1 index+1 index+1 作为当前下标继续搜索
    • t e m p [ i n d e x ] temp[index] temp[index] t e m p [ i ] temp[i] temp[i] 的值再次交换,恢复到交换之前的状态

当每个下标对应的所有可能的值都遍历结束之后,就可以得到数组 n u m s nums nums 的全排列

想法代码

class Solution
{
    IList> permutations = new List>();
    IList temp = new List();
    int n;

    public static void Main(String[] args)
    {
        int[] nums = { 1, 2, 3 };
        Solution solution = new Solution();
        IList> res = solution.Permute(nums);
        foreach (var a in res)
        {
            foreach (var b in a)
            {
                Console.Write(b + " ");
            }
            Console.WriteLine();
        }
    }

    public IList> Permute(int[] nums)
    {
        foreach (int i in nums)
        {
            temp.Add(i);
        }
        n = nums.Length;
        BackTrack(0);
        return permutations;
    }

    public void BackTrack(int index)
    {
        if (index == n)
        {
            permutations.Add(new List(temp));
        }
        else
        {
            for (int i = index; i < n; i++)
            {
                Swap(temp,index,i);
                BackTrack(index+1);
                Swap(temp, index, i);
            }
        }
    }

    public void Swap(IList temp, int index1, int index2)
    {
        int cur = temp[index1];
        temp[index1] = temp[index2];
        temp[index2] = cur;
    }
}

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