1.28回溯(中等)

2024-01-30 04:28
文章标签 中等 回溯 1.28

本文主要是介绍1.28回溯(中等),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1.格雷编码

2. 复原 IP 地址

3. 火柴拼正方形


1.格雷编码

n 位格雷码序列 是一个由 2n 个整数组成的序列,其中:

  • 每个整数都在范围 [0, 2n - 1] 内(含 0 和 2n - 1
  • 第一个整数是 0
  • 一个整数在序列中出现 不超过一次
  • 每对 相邻 整数的二进制表示 恰好一位不同 ,且
  • 第一个 和 最后一个 整数的二进制表示 恰好一位不同

给你一个整数 n ,返回任一有效的 n 位格雷码序列 。

示例 1:

输入:n = 2
输出:[0,1,3,2]
解释:
[0,1,3,2] 的二进制表示是 [00,01,11,10] 。
- 00 和 01 有一位不同
- 01 和 11 有一位不同
- 11 和 10 有一位不同
- 10 和 00 有一位不同
[0,2,3,1] 也是一个有效的格雷码序列,其二进制表示是 [00,10,11,01] 。
- 00 和 10 有一位不同
- 10 和 11 有一位不同
- 11 和 01 有一位不同
- 01 和 00 有一位不同

示例 2:

输入:n = 1
输出:[0,1]

提示:

  • 1 <= n <= 16

分析:感觉从题解来看,这个题好像和回溯没什么很大的关系 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

#include <bits/stdc++.h>
using namespace std;
main()
{int n,i,j,head=1;cin>>n;vector<int> res;res.push_back(0);cout<<0<<" ";for(i=0;i<n;i++){for(j=res.size()-1;j>=0;j--){res.push_back(head+res[j]);cout<<head+res[j]<<" ";}head<<=1;}
}

2. 复原 IP 地址

有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。

  • 例如:"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址,但是 "0.011.255.245""192.168.1.312" 和 "192.168@1.1" 是 无效 IP 地址。

给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 '.' 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。

示例 1:

输入:s = "25525511135"
输出:["255.255.11.135","255.255.111.35"]

示例 2:

输入:s = "0000"
输出:["0.0.0.0"]

示例 3:

输入:s = "101023"
输出:["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]

提示:

  • 1 <= s.length <= 20
  • s 仅由数字组成

分析:这个就是要分割字符串了,刚开始只觉得和回文串是一样的,所以一直在想着一个字符一个字符去判断,结果到后面判断不清楚了,去看了别人的题解才想到完全可以直接用255来判断..

#include <bits/stdc++.h>
using namespace std;
bool isvaild(string s,int start,int end)
{if(start > end) return false;if(s[start]=='0' && start !=end) return false;int i,num=0;for(i=start;i<=end;i++){if(s[i]>'9' || s[i]<'0') return false;num=num*10+s[i]-'0';if(num>255) return false;}return true;
}
void f(string s,int index,int point)
{int i;if(point==3){if(isvaild(s,index,s.size()-1)){cout<<s<<endl;return;}}for(i=index;i<s.size();i++){if(isvaild(s,index,i)){s.insert(s.begin()+i+1,'.');point++;f(s,i+2,point);point--;s.erase(s.begin()+i+1);}else break;}
}
main()
{string s;cin>>s;if(s.size()<4 || s.size()>12) return 0;f(s,0,0);
}

3.火柴拼正方形

你将得到一个整数数组 matchsticks ,其中 matchsticks[i] 是第 i 个火柴棒的长度。你要用 所有的火柴棍 拼成一个正方形。你 不能折断 任何一根火柴棒,但你可以把它们连在一起,而且每根火柴棒必须 使用一次 。

如果你能使这个正方形,则返回 true ,否则返回 false 。

示例 1:

输入: matchsticks = [1,1,2,2,2]
输出: true
解释: 能拼成一个边长为2的正方形,每边两根火柴。

示例 2:

输入: matchsticks = [3,3,3,3,4]
输出: false
解释: 不能用所有火柴拼成一个正方形。

提示:

  • 1 <= matchsticks.length <= 15
  • 1 <= matchsticks[i] <= 108

分析:之前有一道题用了排序,就让我想到了可以先排序,然后算一下总和,通过总和是不是4的倍数和总和/4是不是大于最大值来剪枝,之后就是要用到回溯,在回溯中,如果加和大于总和/4的话就要剪枝,这样可以减少计算量,然后剩下的就是回溯了,我本来想的是用一个字符串s1来记录然后放到4个result中,但是它直接就是result[4],然后从这四个类似于堆的vector下手去做,就简单了好多,感觉真的非常的聪明欸

#include <bits/stdc++.h>
using namespace std;
int num[21],sum=0,n;
vector<int> result(4);
bool f(int index)
{int i;if(index==n) return true;for(i=0;i<4;i++){result[i]+=num[index];if(result[i]<=sum && f(index+1))return true;result[i]-=num[index];}return false;
}
main()
{int i=0,x;while(cin>>x){num[i]=x;sum+=x;i++;}n=i;sort(num,num+n);if(sum%4!=0) {cout<<"false"; return 0;}sum=sum/4;if(num[n-1]>sum) {cout<<"false"; return 0;}if(f(0)) {cout<<"true"; return 0;}else cout<<"false";}

这篇关于1.28回溯(中等)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/659097

相关文章

算法与数据结构面试宝典——回溯算法详解(C#,C++)

文章目录 1. 回溯算法的定义及应用场景2. 回溯算法的基本思想3. 递推关系式与回溯算法的建立4. 状态转移方法5. 边界条件与结束条件6. 算法的具体实现过程7. 回溯算法在C#,C++中的实际应用案例C#示例C++示例 8. 总结回溯算法的主要特点与应用价值 回溯算法是一种通过尝试各种可能的组合来找到所有解的算法。这种算法通常用于解决组合问题,如排列、组合、棋盘游

【经典算法】LeetCode 22括号生成(Java/C/Python3/Go实现含注释说明,中等)

作者主页: 🔗进朱者赤的博客 精选专栏:🔗经典算法 作者简介:阿里非典型程序员一枚 ,记录在大厂的打怪升级之路。 一起学习Java、大数据、数据结构算法(公众号同名) ❤️觉得文章还不错的话欢迎大家点赞👍➕收藏⭐️➕评论,💬支持博主,记得点个大大的关注,持续更新🤞 ————————————————- 首先,请注意题目链接有误,您提供的链接是LeetCode 14,但题目

代码随想三刷回溯篇2

代码随想三刷回溯篇2 39. 组合总和题目代码 40. 组合总和 II题目代码 131. 分割回文串题目代码 93. 复原 IP 地址题目代码 78. 子集题目代码 39. 组合总和 题目 链接 代码 class Solution {public List<List<Integer>> combinationSum(int[] candidates

194.回溯算法:组合总和||(力扣)

代码解决 class Solution {public:vector<int> res; // 当前组合的临时存储vector<vector<int>> result; // 存储所有符合条件的组合// 回溯函数void backtracing(vector<int>& candidates, int target, int flag, int index, vector<bool>&

193.回溯算法:组合总和(力扣)

代码解决 class Solution {public:vector<int> res; // 当前组合的临时存储vector<vector<int>> result; // 存储所有符合条件的组合// 回溯函数void backtrcing(vector<int>& nums, int target, int flag, int index) {// 如果当前组合的和超过了目标值,则返

192.回溯算法:电话号码的字母组合(力扣)

代码解决 class Solution {public:// 定义每个数字对应的字母映射const string letterMap[10] = {"", // 0"", // 1"abc", // 2"def", // 3"ghi", // 4"jkl", // 5"mno", // 6"pqrs", // 7"tuv", // 8"wxyz" // 9}

【C++LeetCode】【热题100】字母异位词分组【中等】-不同效率的题解【3】

题目: 暴力方法: class Solution {public:vector<vector<string>> groupAnagrams(vector<string>& strs) {std::unordered_set<std::string> uniqueWord;//单词字符唯一化集合vector<vector<std::string>> res;//结果for(int i

拉丁矩阵 回溯 c java

现有n种不同形状的宝石,每种宝石有足够多颗。欲将这些宝石排列成m行n列的一个矩阵,m n,使矩阵中每一行和每一列的宝石都没有相同形状。试设计一个算法,计算出对于给定的m和n有多少种不同的宝石排列方案。 方法一:(从左往右,从上往下,依次填写,保证上方,左方没有重复的) import java.util.Scanner;public class LaDingJuZhen3 {static int

排列宝石问题 回溯

问题描述: 现有n种不同形状的宝石,每种n 颗,共n*n颗。同一种形状的n颗宝石分别具有n种不同的颜色c1,c2,…,cn中的一种 颜色。欲将这n*n颗宝石排列成n行n列的一个方阵,使方阵中每一行和每一列的宝石都有n种不同形状和n种不同颜 色。 试设计一个算法,计算出对于给定的n,有多少种不同的宝石排列方案。   算法设计: 对于给定的n,计算出不同的宝石排列方案数。    输入文件示

无优先级运算 回溯 Java

问题描述: 给定n个正整数和4个运算符+,-,*,/,且运算符无优先级,如2+3×5=25。对于任意给定的整数m,试设计一个算 法,用以上给出的n个数和4个运算符,产生整数m,且用的运算次数最少。给出的n个数中每个数最多只能用1次, 但每种运算符可以任意使用 ★ 算法设计:对于给定的n个正整数,设计一个算法,用最少的无优先级运算次数产生 整数m。  输入: n  m     在输入: