题目描述:
给定两个数组,编写一个函数来计算它们的交集。
示例:
//示例1
输入:
1 2 2 1
2 2
输出:
2 2
//示例2
输入:
4 9 5
9 4 9 8 4
输出:
4 9
说明:
思路:
如果使用双重for循环的话需要先将数组去重,使用map容器将元素值与元素个数存储起来,这样做就较为麻烦。我们采取第二种思路,先将数组排序 ,就以升序 为例,使用双指针法 ,指针i
和j
分别指向数组num1
和num2
的头部,如果两指针指向的元素相等,则输出该元素并将两指针分别后移一位;若num1[i]
大于num2[j]
,则指针j
后移一位,i
不变;若num1[i]
小于num2[j]
,则指针i
后移,j
不变。
//c++代码
void jiaoji(int num1[], int num2[]){
//假设数组num1的长度为len1,num2的长度为len2
//先升序排序
sort(num1, num1+len1);
sort(num2, num2+len2);
for(int i=0, j=0; i<len1 && j<len2; ){
if(num1[i] == num2[j]){
cout<<num1[i]<<" ";
i++;
j++
}
else if(num1[i] > num2[j]){
j++;
}
else i++;
}
}
//python代码
def jiaoji(list1, list2):
list1.sort()
list2.sort()
i=j=0
while i<len(list1) and j<len(list2):
if list1[i] == list2[j]:
print(list1[i], end=' ')
elif list1[i] > list2[j]:
j += 1
else:
i += 1
测试:
C++:
#include
#include
#include
using namespace std;
void jiaoji(vector<int> num1, vector<int> num2) {
sort(num1.begin(), num1.end());
sort(num2.begin(), num2.end());
for (int i = 0, j = 0; i<num1.size() && j<num2.size(); ) {
if (num1[i] == num2[j]) {
cout << num1[i] << " ";
i++;
j++;
}
else if (num1[i] < num2[j]) {
i++;
}
else {
j++; }
}
}
int main() {
vector<int> num1, num2;
num1 = {
1,2,2,1,3 };
num2 = {
2,5,9,1,2 };
jiaoji(num1, num2);
return 0;
}
python:
list1 = [1,2,2,1,3]
list2 = [2,5,9,1,2]
def jiaoji(list1, list2):
list1.sort()
list2.sort()
i = j = 0
while i < len(list1) and j < len(list2):
if list1[i] == list2[j]:
print(list1[i], end = ' ')
i += 1
j += 1
elif list1[i] > list2[j]:
j += 1
else:
i += 1
jiaoji(list1, list2)
题目描述:
常规思路:
先确定一个基准元素,如上图的示例1所示,我们不妨令flower
为基准元素。首先创建一个指针p指向基准元素的第一个字符,通过for循环将p指向的字符与其他元素第p个字符(当p指向第一个字符时,p为0)进行比较,如果相等,则p自增,p自增后指向基准元素的第二个字符,同样与其他元素的第p个字符进行比较。当p大于基准元素长度时退出最外层循环。
#include
#include
#include
using namespace std;
string longestCommonPrefix(vector<string>& strs) {
if(strs.size()==0)
return "";
string index = strs[0], res; //res用于记录公共前缀
int p = 0;
if(strs.size()==1)
return index;
if(index.length() < 1)
return "";
while (p < index.length()) {
for (int i = 1; i < strs.size(); i++) {
if(p >= strs[i].length())
return res;
if (strs[i][p] != index[p]) {
if (p == 0)
return "";
else
return res;
}
}
res.insert(res.end(), index[p]); //当基准元素的第p个字符与其他元素的相等时第p的字符为公共字符,插入到res的后面
p++;
}
return res;
}
这种方法运行比较耗时:
进阶思路:
首先找出前两个元素的最长公共前缀,然后找出前两个元素的最长公共前缀 与第三个元素 的最长公共前缀,依此类推,最后得到所有元素的最长公共前缀。
以第一个元素为基准,通过string
类里的find
函数来判断基准元素是否为其他元素的子串(若是find函数会返回字符串第一次出现的索引),由于我们要找的是公共前缀,若返回值为0,即可认定基准元素为其他元素的前缀。
举个例子:
以flow
为基准元素,string s = "flow"
,判断其与fly
(string v = "fly"
)公共前缀的方法是:
s.find(v)
的值不为0,因为s里面不包含v,这时我们将s去掉最后一个字符变为flo
,再判断s.find(v)
的值,很显然,还是不为0,我们再去掉s的最后一个字符变为fl
,再判断时,s.find(v)
等于0,此时可以退出循环,并得到了flow
与fly
的最长公共前缀为fl
。之后,将基准元素变为前两个元素的最长公共前缀,即fl
,使用相同的方法判断fl
与第三个元素的最长公共前缀。就这样,遍历完所有元素后得到所有元素的最长公共前缀。
#include
#include
#include
using namespace std;
string common(vector <string>& strs) {
if (strs.size() == 0)
return "";
string index = strs[0];
int length = index.length();
if (strs.size() == 1)
return index;
if (length < 1)
return "";
for (int i = 1; i < strs.size(); i++) {
while (strs[i].find(index) != 0) {
length--;
if (length == 0)
return "";
index = index.substr(0, length); //去掉最后一个字符
}
if (strs[i].length() == 0) {
return "";
}
}
return index;
}
结果:
从两种方法的运行结果比较得知,第二种方法的效果会更好,执行时间仅有第一种方法的一半。
题目 :
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
int lengthOfLongestSubstring(string s) {
if(s.length()==0)
return 0;
int max = 1;
int k = 0;
int sum = 1;
int j;
for (int i = k + 1; i < s.length(); ) {
for (j = k; j < i; j++) {
if (s[i] == s[j])
break;
}
if (j < i) {
++k;
sum = 1;
i = k + 1;
}
else {
++sum;
if (sum > max)
max = sum;
i++;
}
}
return max;
}
2020.08.25
题目难度 :中等
题目链接 :https://leetcode-cn.com/problems/permutation-in-string/
题目描述 :
给定两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。
class Solution:
def checkInclusion(self, s1: str, s2: str) -> bool:
if len(s1) > len(s2):
return False
dic = {
}
for i in range(ord('a'),ord('z')+1):
dic[chr(i)] = 0
dic_s1 = {
}
for i in s1:
dic_s1[i] = 0
for i in s1:
dic_s1[i] += 1
for i in range(0,len(s1)):
dic[s2[i]] += 1
n = 0
for m in range(len(s1)-1,len(s2)):
ack = True
if m != len(s1)-1:
dic[s2[m]] += 1
dic[s2[n]] -= 1
n += 1
for i in s1:
if dic_s1[i] != dic[i]:
ack = False
break
if ack:
return True
return False
class Solution {
public:
bool checkInclusion(string s1, string s2) {
if(s1.length()>s2.length())
return false;
int dic[26] = {
0};
int dic_s1[26] = {
0};
for(int i=0;i<s1.length();i++){
++dic[s2[i]-'a'];
++dic_s1[s1[i]-'a'];
}
int n = 0;
for(int i=s1.length()-1;i<s2.length();i++){
int ack = 1;
if(i != s1.length()-1){
++dic[s2[i]-'a'];
--dic[s2[n]-'a'];
++n;
}
for(int j=0;j<s1.length();j++){
if(dic_s1[s1[j]-'a']!=dic[s1[j]-'a']){
ack = 0;
break;
}
}
if(ack)
return true;
}
return false;
}
};
两数之和 :
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> record;
for(int i = 0 ; i < nums.size() ; i ++){
int complement = target - nums[i];
if(record.find(complement) != record.end()){
int res[] = {
record[complement],i};
return vector<int>(res, res + 2);
}
record[nums[i]] = i;
}
return vector<int>();
}
三数之和 :
给你一个包含 n 个整数的数组 nums,判断 nums中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
sort(nums.begin(),nums.end());
for(int i=0; i<nums.size();i++){
int index = nums[i];
if(index>0)
break;
int left = i + 1;
int right = nums.size() - 1;
if(i==0 || nums[i] != nums[i-1]){
while(left < right){
if(index + nums[left] + nums[right] < 0){
++left;
}
else if(index + nums[left] + nums[right] > 0){
--right;
}
else{
int p[] = {
index,nums[left], nums[right]};
res.push_back(vector<int>(p,p+3));
while(left<right && nums[left]==nums[left+1]) ++left;
while(left<right && nums[right]==nums[right-1]) --right;
++left;
--right;
}
}
}
}
return res;
}
2020.08.26 星期三 多云
题目难度 :中等
题目链接 :https://leetcode-cn.com/problems/multiply-strings/submissions/
题目描述 :给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
说明:
num1 和 num2 的长度小于110。
num1 和 num2 只包含数字 0-9。
num1 和 num2 均不以零开头,除非是数字 0 本身。
不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。
class Solution {
public:
string multiply(string num1, string num2) {
if(num1 == "0" || num2 == "0")
return "0";
int m = num1.size(), n = num2.size();
auto ans = vector<int>(m+n); //二者相乘,结果最多有m+n位
for(int i=m-1;i>=0;i--){
int x = num1[i] - '0';
for(int j = n-1;j>=0;j--){
int y = num2[j] - '0';
ans[i+j+1] += x*y;
}
}
for(int i=m+n-1;i>0;i--){
ans[i-1] += ans[i]/10;
ans[i] %= 10;
}
int index = ans[0] == 0?1:0;
string s;
while(index<m+n){
s.push_back(ans[index] + '0');
++index;
}
return s;
}
};
参考题解 :https://leetcode-cn.com/problems/multiply-strings/solution/zi-fu-chuan-xiang-cheng-by-leetcode-solution/
2020.08.27 星期四
题目难度 :中等
题目链接 :https://leetcode-cn.com/problems/reverse-words-in-a-string/
题目描述 :给定一个字符串,逐个翻转字符串中的每个单词。
class Solution {
public:
string reverseWords(string s) {
string h;
int num = 0;
int l = 0, r = s.length() - 1;
while (l < r) {
if (s[l] != ' ') {
break;
}
++l;
}
if (l == r) {
if(s[r]!=' ')
{
h.push_back(s[r]);
return h;}
else
return "";
}
while (r>l) {
if (s[r] != ' ') {
break;
}
--r;
}
int m_l, n_r;
int ack = 0;
for (int i = r; i >= l; i--) {
if (s[i] != ' '&&ack==0) {
ack = 1;
num = 0;
n_r = i;
}
if (s[i] == ' ') {
ack = 0;
num++;
m_l = i + 1;
}
if (i == l) {
ack = 0;
num++;
m_l = l;
}
if (num == 1) {
for (int j = m_l; j <= n_r; j++) {
h.push_back(s[j]);
}
if (m_l != l) {
h.push_back(' ');
}
}
}
return h;
}
};
2020.08.28 星期五
题目难度 :中等
题目描述 :以 Unix 风格给出一个文件的绝对路径,你需要简化它。或者换句话说,将其转换为规范路径。
在 Unix 风格的文件系统中,一个点(.
)表示当前目录本身;此外,两个点 (..
) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。
请注意,返回的规范路径必须始终以斜杠 /
开头,并且两个目录名之间必须只有一个斜杠 /
。最后一个目录名(如果存在)不能以 /
结尾。此外,规范路径必须是表示绝对路径的最短字符串。
思路简述 :使用栈的数据结构,先按照"/
"将字符串分割,按照顺序依次入栈,如果遍历到..
时,栈顶弹出,遇到''
或.
时不执行任何操作
class Solution:
def simplifyPath(self, path: str) -> str:
path = path.split('/')
stack = []
for item in path:
if item == '..':
if stack:
stack.pop()
elif item != '.' and item != '':
stack.append(item)
else:
continue
return '/' + '/'.join(stack)
2020.08.30 星期日
题目难度 :中等
题目描述 :
给定一个包含了一些 0 和 1 的非空二维数组 grid 。
一个 岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在水平或者竖直方向上相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。
找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为 0 )
int num;
class Solution {
public:
//1: no left 2: no right 3: no up 4: no down
void sum(vector<vector<int>> &v, int x, int y, int ack){
v[x][y] = 0;
if (ack != 1 && y - 1 >= 0) {
if (v[x][y - 1] != 0) {
num++;
sum(v, x, y - 1, 2);
}
}
if (ack != 2 && y + 1 < v[0].size()) {
if (v[x][y + 1] != 0) {
num++;
sum(v, x, y + 1, 1);
}
}
if (ack != 3 && x - 1 >= 0) {
if (v[x - 1][y] != 0) {
num++;
sum(v, x - 1, y, 4);
}
}
if (ack != 4 && x + 1 < v.size()) {
if (v[x + 1][y] != 0) {
num++;
sum(v, x + 1, y, 3);
}
}
else
return;
}
int maxAreaOfIsland(vector<vector<int>>& grid) {
int max = 0;
for(int x=0; x<grid.size();x++){
for(int y=0;y<grid[0].size();y++){
if(grid[x][y]==1){
num = 1;
sum(grid,x,y,0);
if(num>max)
max = num;
}
}
}
return max;
}
};
2020.08.31 星期一
题目难度 :中等
题目描述 :有 N 个房间,开始时你位于 0 号房间。每个房间有不同的号码:0,1,2,…,N-1,并且房间里可能有一些钥匙能使你进入下一个房间。
在形式上,对于每个房间 i 都有一个钥匙列表 rooms[i]
,每个钥匙 rooms[i][j]
由 [0,1,...,N-1]
中的一个整数表示,其中 N = rooms.length
。 钥匙 rooms[i][j] = v
可以打开编号为 v 的房间。最初,除 0 号房间外的其余所有房间都被锁住。你可以自由地在房间之间来回走动。如果能进入每个房间返回 true,否则返回 false。
解法一 :深度优先搜索
class Solution {
public:
void find(vector<vector<int>> v,vector<int> s, int *p){
for(int i=0;i<s.size();i++){
if(p[s[i]] > 0)
continue;
++p[s[i]];
vector<int> c;
for(int j=0;j<v[s[i]].size();j++){
c.push_back(v[s[i]][j]);
}
find(v,c,p);
}
return;
}
bool canVisitAllRooms(vector<vector<int>>& rooms) {
int room[1000] = {
0};
room[0] = 1000;
vector<int> s;
for(int i=0;i<rooms[0].size();i++){
s.push_back(rooms[0][i]);
}
find(rooms,s,room);
for(int i=0;i<rooms.size();i++){
if(room[i] == 0)
return false;
}
return true;
}
};
解法二 :深度优先搜索改进版
class Solution {
public:
int num;
vector<int> v;
void ans(vector<vector<int>>& s, int ack){
num++;
v[ack] = true;
for(auto& t:s[ack]){
if(!v[t]){
ans(s,t);
}
}
}
bool canVisitAllRooms(vector<vector<int>>& rooms) {
num = 0;
int n = rooms.size();
v.resize(n);
ans(rooms,0);
return num==n;
}
};
2020.09.01 星期二
题目难度 :中等
题目描述 :假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。
class Solution {
public:
int search(vector<int>& nums, int target) {
int n = (int)nums.size();
if (!n) return -1;
if (n == 1) return nums[0] == target ? 0 : -1;
int l = 0, r = n - 1;
while (l <= r) {
int mid = (l + r) / 2;
if (nums[mid] == target) return mid;
if (nums[0] <= nums[mid]) {
if (nums[0] <= target && target < nums[mid]) {
r = mid - 1;
} else {
l = mid + 1;
}
} else {
if (nums[mid] < target && target <= nums[n - 1]) {
l = mid + 1;
} else {
r = mid - 1;
}
}
}
return -1;
}
};
2020.09.02 星期三
题目难度 :简单
题目描述 :给定一个未经排序的整数数组,找到最长且连续的的递增序列,并返回该序列的长度。
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
if(nums.size()==0)
return 0;
if(nums.size()==1)
return 1;
int max = 1;
int num = 1;
for(int i=0;i<nums.size()-1;i++){
if(nums[i+1]>nums[i]){
num++;
if(num>max)
max = num;
}
else{
num = 1;
}
}
return max;
}
};
2020.09.03 星期四
题目难度 :困难
题目描述 :给定一个未排序的整数数组,找出最长连续序列的长度。
要求算法的时间复杂度为 O(n)。
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
if(nums.size()==0 || nums.size()==1)
return nums.size();
sort(nums.begin(), nums.end());
int left = 1;
int max = 1;
int num = 1;
while(left<nums.size()){
if(nums[left] == nums[left-1] + 1){
num++;
if(num>max)
max = num;
}
else if(nums[left]!=nums[left-1]){
num = 1;
}
else
num = num;
left++;
}
return max;
}
};
2020.09.05 星期六
题目难度 :中等
题目链接 :https://leetcode-cn.com/problems/permutation-sequence/
题目描述 :
class Solution {
public:
string getPermutation(int n, int k) {
vector<int> factorial(n);
factorial[0] = 1;
for (int i = 1; i < n; ++i) {
factorial[i] = factorial[i - 1] * i;
}
--k;
string ans;
vector<int> valid(n + 1, 1);
for (int i = 1; i <= n; ++i) {
int order = k / factorial[n - i] + 1;
for (int j = 1; j <= n; ++j) {
order -= valid[j];
if (!order) {
ans += (j + '0');
valid[j] = 0;
break;
}
}
k %= factorial[n - i];
}
return ans;
}
};
2020.09.05 星期六
题目难度 :中等
题目描述 :班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。
给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。如果M[i][j] = 1
,表示已知第 i 个和 j 个学生互为朋友关系,否则为不知道。你必须输出所有学生中的已知的朋友圈总数。
class Solution {
public:
int num = 0;
void cmp(vector<vector<int>>& v, int *a, int k){
for(int i = 0; i<v.size(); i++){
if(v[k][i] == 1 && k != i){
if(a[i]==0)
continue;
else{
a[i] = 0;
cmp(v, a, i);
}
}
}
}
int findCircleNum(vector<vector<int>>& M) {
int *p = new int[M.size()];
for(int i=0; i<M.size(); i++)
p[i] = 1;
for(int i=0;i<M.size();i++){
if(p[i]==1){
if(i==0)
p[0]=0;
num++;
cmp(M,p,i);
}
}
return num;
}
};
2020.09.06 星期日
题目难度 :中等
题目描述 :给你一个字符串 s 和一个整数数组 cost ,其中 cost[i] 是从 s 中删除字符 i 的代价。
返回使字符串任意相邻两个字母不相同的最小删除成本。
请注意,删除一个字符后,删除其他字符的成本不会改变。
class Solution {
public:
int minCost(string s, vector<int>& cost) {
int i;
for(i=0;i<s.size()-1;i++){
if(s[i]==s[i+1])
break;
}
if(i>=s.size()-1)
return 0;
int sum = 0;
int l=0;
int r=1;
while(r<s.size()){
if(s[l]==s[r]){
while(s[l]==s[r])
r++;
vector<int> t;
for(int j=l;j<r;j++)
t.push_back(cost[j]);
sort(t.begin(),t.end());
for(int j=0;j<t.size()-1;j++)
sum += t[j];
l = r;
r++;
}
else{
++l;
++r;
}
}
return sum;
}
};
优化一下代码 :
class Solution {
public:
int minCost(string s, vector<int>& cost) {
int sum = 0;
int l=0;
int r=1;
while(r<s.size()){
if(s[l]==s[r]){
while(s[l]==s[r])
r++;
int ack = 0;
int max = 0;
for(int j=l;j<r;j++){
if(cost[j]>max)
max = cost[j];
ack += cost[j];
}
sum += ack - max;
l = r;
r++;
}
else{
++l;
++r;
}
}
return sum;
}
};
可以看到,代码执行时间和内存占用都得到了明显的优化。
2020.09.07 星期一
题目难度 :中等
题目描述 :给出一个区间的集合,请合并所有重叠的区间。
class Solution {
public:
static bool cmp(vector<int> a, vector<int> b){
return a[0] < b[0];
}
vector<vector<int>> merge(vector<vector<int>>& intervals) {
if(intervals.size() == 1 || intervals.size() == 0)
return intervals;
vector<vector<int>> v;
sort(intervals.begin(), intervals.end(), cmp);
v.push_back(intervals[0]);
int p = 0;
for(int i=1;i<intervals.size();i++){
if(intervals[i][0] <= v[p][1] && intervals[i][1] > v[p][1]){
v[p][1] = intervals[i][1];
}
if(intervals[i][0] > v[p][1]){
vector<int> s;
s.push_back(intervals[i][0]);
s.push_back(intervals[i][1]);
v.push_back(s);
p++;
}
}
return v;
}
};
代码优化 :
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
if (intervals.size() == 0) {
return {
};
}
sort(intervals.begin(), intervals.end());
vector<vector<int>> merged;
for (int i = 0; i < intervals.size(); ++i) {
int L = intervals[i][0], R = intervals[i][1];
if (!merged.size() || merged.back()[1] < L) {
merged.push_back({
L, R});
}
else {
merged.back()[1] = max(merged.back()[1], R);
}
}
return merged;
}
};
2020.09.08 星期二
题目难度 :中等
题目描述 :给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
void backTrack(int n, int k, int index){
if(path.size() == k){
res.push_back(path);
return;
}
for(int i = index; i <= n - (k - path.size()) + 1; i++){
path.push_back(i);
backTrack(n, k, i + 1);
path.pop_back();
}
}
vector<vector<int>> combine(int n, int k) {
backTrack(n, k, 1);
return res;
}
};
2020.09.10 星期四
题目难度 :中等
题目描述 :给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:
所有数字(包括目标数)都是正整数。
解集不能包含重复的组合。
class Solution {
public:
vector<vector<int>> res;
vector<int> s;
void backTrack(vector<int>& candidates, int target, int sum, int index, vector<bool>& used){
if(sum > target)
return;
if(sum == target){
res.push_back(s);
return;
}
for(int i=index; i<candidates.size();i++){
if( i>0 && used[i-1]==false&& candidates[i-1]==candidates[i] )
continue;
sum += candidates[i];
s.push_back(candidates[i]);
used[i] = true;
backTrack(candidates, target, sum,i+1, used);
used[i] = false;
s.pop_back();
sum -= candidates[i];
}
}
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
vector<bool> used(candidates.size(), false);
sort(candidates.begin(),candidates.end());
backTrack(candidates, target,0,0,used);
return res;
}
};
2020.09.11 星期五
题目难度 :正等
题目描述 :找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。
说明:
class Solution {
public:
vector<vector<int>> res;
vector<int> s;
void backTrack(vector<int>& v, int ack, int k, int sum, int n, int index){
if(ack > k)
return;
if(ack == k && sum != n)
return;
if(ack == k && sum == n){
res.push_back(s);
return;
}
for(int i = index; i < 9; i++){
sum += v[i];
s.push_back(v[i]);
backTrack(v, ack + 1, k, sum, n, i+1);
s.pop_back();
sum -= v[i];
}
}
vector<vector<int>> combinationSum3(int k, int n) {
int p[] = {
1,2,3,4,5,6,7,8,9};
vector<int> jk(p, p+9);
backTrack(jk, 0, k, 0, n, 0);
return res;
}
};
每日更新!!!