给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。
示例:
输入: n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combinations
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
回溯
class Solution {
private:
vector> result;
public:
//回溯
vector> combine(int n, int k)
{
vector arr;
for(int i = 1; i <= n; i++) {
arr.push_back(i);
}
combine(arr, {}, 0, k);
return result;
}
void combine(vector arr, vector temp, int start, int k)
{
if(temp.size() == k) {
result.push_back(temp);
return;
}
for(int i = start; i < arr.size(); i ++) {
temp.push_back(arr[i]);
combine(arr, temp, i + 1, k);
temp.pop_back();
}
return;
}
};
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/subsets
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
回溯
class Solution {
//回溯
private:
vector> result;
public:
vector> subsets(vector& nums)
{
subsets(nums, {}, 0);
return result;
}
void subsets(vector& nums, vector temp, int pos)
{
if(temp.size() <= nums.size()) {
result.push_back(temp);
} else {
return;
}
for(int i = pos; i < nums.size(); i++) {
temp.push_back(nums[i]);
subsets(nums, temp, i + 1);
temp.pop_back();
}
return;
}
};
给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例:
board =
[
['A','B','C','E'],
['S','F','C','S'],
['A','D','E','E']
]给定 word = "ABCCED", 返回 true
给定 word = "SEE", 返回 true
给定 word = "ABCB", 返回 false
提示:
board 和 word 中只包含大写和小写英文字母。
1 <= board.length <= 200
1 <= board[i].length <= 200
1 <= word.length <= 10^3来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-search
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
深度优先搜索
class Solution {
//回溯 or 深度优先搜索
public:
bool exist(vector>& board, string word)
{
for(int i = 0; i < board.size(); i++) {
for(int j = 0; j < board[0].size(); j++) {
if(exist(board, i, j, word, 0)) {
return true;
}
}
}
return false;
}
bool exist(vector> &board, int i, int j, string word, int pos)
{
if(board[i][j] != word[pos]) {
return false;
}
if(pos == word.size() - 1) {
return true;
}
char temp = board[i][j];
board[i][j] = '0';
pos += 1;
if((i - 1 >= 0 && exist(board, i - 1, j, word, pos)) || (j - 1 >= 0 && exist(board, i, j - 1, word, pos)) ||
(i + 1 < board.size() && exist(board, i + 1, j, word, pos)) || (j + 1 < board[0].size() && exist(board, i, j + 1, word, pos))) {
return true;
}
board[i][j] = temp;
return false;
}
};
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定 nums = [1,1,1,2,2,3],
函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。
你不需要考虑数组中超出新长度后面的元素。
示例 2:给定 nums = [0,0,1,1,1,1,2,3,3],
函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。
你不需要考虑数组中超出新长度后面的元素。
说明:为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
原地删除
class Solution {
public:
/**
int removeDuplicates(vector& nums) {
int length = 0;
auto start = nums.begin();
for(auto iter = nums.begin(); iter != nums.end(); iter++) {
if(count(nums.begin(), start, *iter) < 2) {
*start = *iter;
start ++;
length ++;
}
}
return length;
}
*/
int removeDuplicates(vector& nums)
{
int i = 0;
for(int num: nums) {
if(i < 2 || nums[i - 2] < num) {
nums[i++] = num;
}
}
return i;
}
};