首页 > 编程语言 >代码随想录算法训练营第二十五天|LeetCode491.递增子序列、46.全排列、47.全排列II、322.重新安排行程、51.N皇后、37.解数独

代码随想录算法训练营第二十五天|LeetCode491.递增子序列、46.全排列、47.全排列II、322.重新安排行程、51.N皇后、37.解数独

时间:2024-11-24 13:59:17浏览次数:8  
标签:排列 nums int res 随想录 322 new path public

前言

打卡代码随想录算法训练营第49期第二十五天  ○( ^皿^)っHiahiahia…

首先十分推荐学算法的同学可以先了解一下代码随想录,可以在B站卡哥B站账号、代码随想录官方网站代码随想录了解,卡哥清晰易懂的算法教学让我直接果断关注,也十分有缘和第49期的训练营大家庭一起进步。


今日题目

在学习今日的题目前先看:回溯理论(文字)卡哥讲解 —— 回溯理论

LeetCode 491 递增子序列

题目链接:491 递增子序列

文章讲解:递增子序列

视频讲解:卡哥讲解 —— 递增子序列

本题使用了新的去重方式,原因是因为之前的used去重只适用于有序数组,而本题无法做到有序,所以使用HashSet来进行本层去重。

public class Solution {
    public List<IList<int>> res = new List<IList<int>>();
    public List<int> path = new List<int>();
    public IList<IList<int>> FindSubsequences(int[] nums) {
        BackTracking(nums , 0);
        return res;
    }
    public void BackTracking(int[] nums , int startIndex)
    {
        if(path.Count >= 2)
            res.Add(new List<int>(path));
        //使用哈希来进行本层去重
        HashSet<int> hs = new HashSet<int>();
        for(int i = startIndex; i < nums.Length; i++)
        {
            //本层去重
            if(path.Count > 0 && nums[i] < path[path.Count - 1] || hs.Contains(nums[i]))
                continue;
            hs.Add(nums[i]);
            path.Add(nums[i]);
            BackTracking(nums , i + 1);
            path.RemoveAt(path.Count - 1);//回溯
        }
    }
}

LeetCode 46 全排列

题目链接:46 全排列

文章讲解:全排列

视频讲解:卡哥讲解 —— 全排列

本题明确说了所有元素不相同,所以直接使用used就可以解决。

public class Solution {
    public List<IList<int>> res = new List<IList<int>>();
    public List<int> path = new List<int>();
    public IList<IList<int>> Permute(int[] nums) {
        //使用used记录使用过的元素
        int[] used = new int[nums.Length];
        BackTracking(nums , used);
        return res;
    }
    public void BackTracking(int[] nums , int[] used)
    {
        //当记录数量等于数组数量 则可以加入
        if(path.Count == nums.Length)
        {
            res.Add(new List<int>(path));
            return;
        }
        for(int i = 0; i < nums.Length; i++)
        {
            if(used[i] == 1)//used[i] = 1代表元素使用过
                continue;
            path.Add(nums[i]);
            used[i] = 1;
            BackTracking(nums , used);
            used[i] = 0;//回溯
            path.RemoveAt(path.Count - 1);//回溯
        }
    }
}

LeetCode 47 全排列II

题目链接:47 全排列 II

文章讲解:全排列 II

视频讲解:卡哥讲解 —— 全排列 II

这个题目和全排列基本一致,就是多了数组中有重复元素的条件,那么就需要用HashSet进行单层去重,剩下完全一致。

public class Solution {
    public List<IList<int>> res = new List<IList<int>>();
    public List<int> path = new List<int>();
    public IList<IList<int>> PermuteUnique(int[] nums) {
        int[] used = new int[nums.Length];
        BackTracking(nums , used);
        return res;
    }
    public void BackTracking(int[] nums , int[] used)
    {
        if(path.Count == nums.Length)
        {
            res.Add(new List<int>(path));
            return;
        }
        //单层去重
        HashSet<int> hs = new HashSet<int>();
        for(int i = 0; i < nums.Length; i++)
        {
            if(used[i] == 1 || hs.Contains(nums[i]))
                continue;
            hs.Add(nums[i]);
            path.Add(nums[i]);
            used[i] = 1;
            BackTracking(nums , used);
            used[i] = 0;//回溯
            path.RemoveAt(path.Count - 1);//回溯
        }
    }
}

LeetCode 332 重新安排行程

题目链接:332 重新安排行程

文章讲解:重新安排行程

本题十分复杂,建议直接看代码随想录网站内容。

public class Solution {
    //dic<出发机场,dic<到达机场,到达次数>>
    public Dictionary<string, Dictionary<string,int>> targets = new Dictionary<string, Dictionary<string,int>>();
    public LinkedList<string> res = new LinkedList<string>(); 
    public IList<string> FindItinerary(IList<IList<string>> tickets) {

        foreach (var list in tickets) {
            string from = list[0];//起始位置
            string to = list[1];//到达位置
            //添加对应关系
            if(!targets.TryGetValue(from, out var temp))
            {
                temp = new Dictionary<string, int>();
                targets.Add(from, temp);
            }
            if(temp.ContainsKey(to))
                temp[to] += 1;
            else
                temp.Add(to , 1);
        }

        res.AddLast("JFK");
        BackTracking(tickets.Count);
        return res.ToList();
    }
    public bool BackTracking(int ticketNum)
    {
        //终止条件根据规律可以得到为票数 + 1
        if(res.Count == ticketNum + 1)
            return true;

        //上一站的到达的位置
        string currentPlace = res.Last();
        //如果不存在这里出发的机票 则返回false
        if(!targets.ContainsKey(currentPlace)) 
            return false;
        var dic = targets[currentPlace].OrderBy(x=>x.Key).ToDictionary(x=>x.Key, x=>x.Value)/*排序 先走排序靠前的*/;
        foreach(var ticket in dic)
        {
            if(ticket.Value > 0)
            {
                res.AddLast(ticket.Key);
                targets[currentPlace][ticket.Key] -= 1;
                //判断走这条路行不行的通
                if(BackTracking(ticketNum))
                    return true;
                res.RemoveLast();//回溯
                targets[currentPlace][ticket.Key] += 1;//回溯
            }
        }
        //到这里证明没有任意一条路可以满足条件,只能返回上一次再寻找
        return false;
    }
}

LeetCode 51 N皇后

题目链接:51 N皇后

文章讲解:N皇后

视频讲解:卡哥讲解 —— N皇后

本题十分复杂,建议直接看代码随想录网站内容与卡哥讲解内容。

public class Solution {
    public List<IList<string>> res = new List<IList<string>>();
    public IList<IList<string>> SolveNQueens(int n) {
        //初始化棋盘
        char[][] board = new char[n][];
        for(int i = 0; i < n; i++)
        {
            board[i] = new char[n];
            for(int j = 0; j < n; j++)
            {
                board[i][j] = '.';
            }
        }
        BackTracking(n , 0 , board);
        return res;
    }
    public void BackTracking(int n , int row , char[][] chessBoard)
    {
        if(row == n)//终止条件
        {
            res.Add(chessBoard.Select(x => new string(x)).ToList());
            return;
        }
        for(int i = 0; i < n; i++)
        {
            if(CheckCanIn(chessBoard , row , i , n))
            {
                chessBoard[row][i] = 'Q';
                BackTracking(n , row + 1 , chessBoard);
                chessBoard[row][i] = '.';//回溯
            }
        }
    }
    //检测该位置是否能放入皇后
    public bool CheckCanIn(char[][] chessBoard , int row/*行*/ , int col/*列*/ , int n)
    {
        for(int i = 0; i < row; i++)
        {
            if(chessBoard[i][col] != '.')
                return false;
        }
        for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--)
        {
            if (chessBoard[i][j] == 'Q') 
                return false;
        }
        for (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++)
        {
            if (chessBoard[i][j] == 'Q') 
                return false;
        }
        return true;
    }
}

LeetCode 37 解数独

题目链接:37 解数独

文章讲解:解数独

视频讲解:卡哥讲解 —— 解数独

本题十分复杂,建议直接看代码随想录网站内容与卡哥讲解内容。

public class Solution {
    public void SolveSudoku(char[][] board) {
        BackTracking(board);
    }
    public bool BackTracking(char[][] board)
    {
       for(int i = 0; i < board.Length; i++)
       {
            for(int j = 0; j < board[0].Length; j++)
            {
                //找到需要填数的位置
                if(board[i][j] != '.')
                    continue;
                //从1 - 9挨个试
                for(char k = '1'; k <= '9'; k++)
                {
                    if(IsValid(board , i , j , k))
                    {
                        board[i][j] = k;
                        if(BackTracking(board))
                            return true;
                        board[i][j] = '.';//回溯
                    }
                }
                return false;
            }
       }
       return true;
    }
    //判断是否可以填某个数字
    public bool IsValid(char[][] board, int row/*行*/, int col/*列*/, char val)
    {
        for (int i = 0; i < 9; i++)//判断这一列是否有相同数字
        {
            if (board[i][col] == val) return false;
        }
        for (int i = 0; i < 9; i++)//判断这一行是否有相同数组
        {
            if (board[row][i] == val) return false;
        }
        //判断3 * 3内是否有相同数字
        int startRow = (row / 3) * 3;
        int startCol = (col / 3) * 3;
        for (int i = startRow; i < startRow + 3; i++)
        {
            for (int j = startCol; j < startCol + 3; j++)
            {
                if (board[i][j] == val) return false;
            }
        }
        //前面都没返回false 则可以填写此数
        return true;
    }
}

学完回溯,在看看:回溯总结

今天的后三道题算是比较难的内容,需要反复练习哦,明天见~~~

标签:排列,nums,int,res,随想录,322,new,path,public
From: https://blog.csdn.net/tancxiaohei23/article/details/143997731

相关文章

  • CSS文本属性:字体、加粗、斜体、对齐方式、下划线、首行缩进、字母大小写、字间距,词间
    1.非常常用!!!字体大小:16px、18pxfont-size:大小;字体颜色:red、green、#ff0000、#f00(两个相同的可以省略一个)coror:颜色;2.字体设置字体:Arial,Verdana,Thoma,sans-serif,simsun.....font-family:字体;3.加粗font-weight:xx;xx:下面的单词或整百数值(100-900)。    nor......
  • 三种排列 dp 的比较
    三种排列dp的比较Permutation有一个长为NNN的正整数排列。给定一个由<和>组成长为N−......
  • 代码随想录刷题学习日记
    仅为个人记录复盘学习历程,解题思路来自代码随想录代码随想录刷题笔记总结网址:代码随想录376.摆动序列如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。给定一个整数序列,......
  • 代码随想录算法训练营第十三天| 110.平衡二叉树、257. 二叉树的所有路径、404.左叶子
    110.平衡二叉树题目链接:.-力扣(LeetCode)文章链接:代码随想录视频链接:后序遍历求高度,高度判断是否平衡|LeetCode:110.平衡二叉树_哔哩哔哩_bilibili《代码随想录》算法公开课开讲啦!快来打卡!本期视频的文字讲解版在「代码随想录」刷题网站:programmercarl.com,这里刷题顺序,详......
  • 【代码随想录Day50】图论Part02
    岛屿数量深搜题目链接/文章讲解:代码随想录classSolution{//计算网格中岛屿的数量publicintnumIslands(char[][]grid){intsum=0;//初始化岛屿数量为0//遍历整个网格for(inti=0;i<grid.length;i++){......
  • 代码随想录刷题学习日记
    仅为个人记录复盘学习历程,解题思路来自代码随想录代码随想录刷题笔记总结网址:代码随想录二叉树理论基础学习二叉树有两种主要的形式:满二叉树和完全二叉树。满二叉树:只有度为0的结点和度为2的结点,且度为0的结点在同一层的二叉树。深度为k,有2^k-1个节点。完全二叉树:除了最......
  • 代码随想录打卡Day3
    链表:通过指针链接的线性数据结构。链表由两部分组成,一为数据域,一为指针域。并与结构体有很大关系,链表的节点一般都是结构体,其中包含了该节点的数据部分以及指向下一节点的指针。通过这种方式,链表将结构体与指针连接起来,从而构建一个强大的数据结构,可以同时实现数据的组织和动......
  • 代码随想录|二叉树part 03
    求普通二叉树的节点数量要点:将子节点的个数记录到父节点,使用后序遍历classSolution{public:intmaxDepth(TreeNode*root){if(root==NULL)return0;intleft1=maxDepth(root->left);intright1=maxDepth(root->right);intnum=......
  • 代码随想录|二叉树part 02
    翻转二叉树要点:指针交换优先利用前序或后序遍历,若采用中序遍历(则两次采用遍历左子树)classSolution{public:TreeNode*invertTree(TreeNode*root){if(root==NULL)returnroot;swap(root->left,root->right);invertTree(root->left);......
  • 代码随想录训练营第58天|统计相邻
    110.字符串接龙#include<iostream>#include<vector>#include<string>#include<unordered_set>#include<unordered_map>#include<queue>usingnamespacestd;intmain(){stringbeginStr,endStr,str;intn;ci......