两周小结

17. 电话号码的字母组合

题目描述
给定一个仅包含数字 2-9 的字符串,返回所有可能的字母组合。数字到字母的映射与电话按键相同(例如,2 对应 "abc",3 对应 "def" 等)。

解题思路
采用回溯法,递归生成所有可能的组合。每次处理一个数字,遍历其对应的字母,添加到当前路径中,递归处理下一个数字,直到组合长度等于输入长度时保存结果。

代码实现

点击查看代码
class Solution {
public:
        const string map[10]=
        {
            "",
            "",
            "abc",
            "def",
            "ghi",
            "jkl",
            "mno",
            "pqrs",
            "tuv",
            "wxyz",
        };
        vector<string>result;
        string path;
        void dfs(string digits,int index)
        {
                if(index==digits.size())
                {
                    result.push_back(path);
                    return;
                }
            int number=digits[index]-'0';
            string letters=map[number];
            for(int i=0;i<letters.size();i++)
            {
                path.push_back(letters[i]);
                dfs(digits,index+1);
                path.pop_back();
            }

        }
    vector<string> letterCombinations(string digits) {
        if(digits.empty()) return result;
        dfs(digits,0);
        return result;
        
    }
};

22. 括号生成

题目描述
给定一个整数 n,生成所有有效的括号组合,要求每个组合包含 n 对括号。

解题思路
回溯法,维护当前字符串、左括号和右括号的数量。添加左括号的条件是数量小于 n,添加右括号的条件是数量小于左括号。

代码实现

点击查看代码
class Solution {
public:
    vector<string> res;
    vector<string> generateParenthesis(int n) {
        dfs("",n,n);
        return res;
    }
    void dfs(const string& str,int left,int right)
    {
        if(left<0||left>right) return;
        if(left==0&&right==0) 
        {
            
            res.push_back(str);
            return;
        }
        dfs(str+'(',left-1,right);
        dfs(str+')',left,right-1);
    }
};

46. 全排列

题目描述
给定一个不含重复数字的数组 nums,返回所有可能的全排列。

解题思路
回溯法,通过交换元素的位置生成不同的排列。每次固定一个位置,递归处理剩余元素。

代码实现

点击查看代码
class Solution {
public:
   void backtrack(vector<vector<int>>& res, vector<int>& output, int first, int len){
        if (first == len) {
            res.emplace_back(output);
            return;
        }
        for (int i = first; i < len; ++i) {
            swap(output[i], output[first]);
            backtrack(res, output, first + 1, len);
            swap(output[i], output[first]);
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int> > res;
        backtrack(res, nums, 0, (int)nums.size());
        return res;
    }

};

89. 格雷编码

题目描述
给定整数 n,返回任一有效的 n 位格雷编码序列。相邻两个数的二进制表示仅有一位不同。

解题思路
利用格雷码公式 G(n) = n ^ (n >> 1),直接生成序列。

代码实现

点击查看代码
class Solution {
public:
    vector<int> grayCode(int n) {
        vector<int> ans;
        int m=1<<n;
        for(int i=0;i<m;i++) ans.push_back(i^i>>1);
        return ans;
    }
};

113. 路径总和 II

题目描述
给定二叉树和一个目标值,找出所有从根到叶的路径,使得路径和等于目标值。

解题思路
深度优先搜索(DFS),记录路径。当到达叶子节点且路径和等于目标值时,保存路径。

代码实现

点击查看代码
class Solution {
public:
    vector<vector<int>> ret;
    vector<int> path;
    void dfs(TreeNode*root,int targetSum)
    {
        if(root==nullptr) return;
        path.emplace_back(root->val);
        targetSum-=root->val;
        if(root->left==nullptr&&root->right==nullptr&&targetSum==0)
        {
            ret.emplace_back(path);
        }
        dfs(root->left,targetSum);
        dfs(root->right,targetSum);
        path.pop_back();
    }
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        dfs(root,targetSum);
        return ret;
    }
};

A-分糖果(河南省赛)

题目描述
幼儿园准备了n包糖果,每包糖果里有1。2或3颗美味的糖果。现在需要将这些这些糖果平分给两个表现优异的小朋友以作奖励,为了公平公正,需要确保两位小朋友分得的糖果颗数相等,且每一包糖果都需要分给正好一位小朋友。幼儿园园长委托你帮忙判断下:是否存在可行的分配方法?

解题思路
暴力记录1,2,3的糖果个数,然后依次判断,用flag记录状态,根据状态输出YES或NO。

代码实现

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n,a=0,b=0,c=0;
	
	cin>>n;
	while(n--)
	{
		int x;
		cin>>x;
		switch(x)
		{
			case 1:
				a++;
				break;
			case 2:
				b++;
				break;
			case 3:
				c++;
				break;
			
		}
	}
	if((a+2*b+3*c)%2==1)
	{
		cout<<"NO";
		return 0;
	}
	int flag=0;
	for(int i=0;i<=a;i++)
	{
		for(int j=0;j<=b;j++)
		{
			for(int k=0;k<=c;k++)
			{
				if(i+2*j+3*k==(a-i)+2*(b-j)+3*(c-k))
				{
					flag=1;
					cout<<"YES"<<endl;
					return 0;
				}
			}
			
		}
		
	}
	if(!flag)cout<<"NO"<<endl;
	return 0;
}

1971. 寻找图中是否存在路径
题目描述
判断图中从起点到终点是否存在路径。

解题思路
并查集判断连通性。

代码实现

点击查看代码
class Solution {
public:
    bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
        vector<int> p(n);
        iota(p.begin(),p.end(),0);
        function<int(int)> find=[&](int x)->int{
            if(p[x]!=x) p[x]=find(p[x]);
            return p[x];
        };
        for(auto& e:edges)p[find(e[0])]=find(e[1]);
        return find(source)==find(destination);
    }
};

695. 岛屿的最大面积
题目描述
给定二维矩阵,1 表示陆地,0 表示水,求最大岛屿面积。

解题思路
深度优先搜索(DFS),遍历每个岛屿并计算面积。

**代码实现*

点击查看代码
class Solution {
  int dfs(vector<vector<int>>& grid, int cur_i, int cur_j) {
        if (cur_i < 0 || cur_j < 0 || cur_i == grid.size() || cur_j == grid[0].size() || grid[cur_i][cur_j] != 1) {
            return 0;
        }
        grid[cur_i][cur_j] = 0;
        int di[4] = {0, 0, 1, -1};
        int dj[4] = {1, -1, 0, 0};
        int ans = 1;
        for (int index = 0; index != 4; ++index) {
            int next_i = cur_i + di[index], next_j = cur_j + dj[index];
            ans += dfs(grid, next_i, next_j);
        }
        return ans;
    }
public:
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int ans=0;
        for(int i=0;i!=grid.size();++i)
        {
            for(int j=0;j!=grid[0].size();++j)
            {
                ans=max(ans,dfs(grid,i,j));
            }
        }
        return ans;
    }
};
*
posted on 2025-05-04 19:51  好好好好好好好好好  阅读(17)  评论(0)    收藏  举报