数字排列
题意
有重复数字的全排列。
dfs思路
1 2 2 3 ,枚举到第3个数,我们固定一个顺序,把第2个2放在第1个2之后。
代码
class Solution {
public:
vector<vector<int>>res;
vector<bool>st;
vector<int>path;
vector<vector<int>> permutation(vector<int>& nums) {
sort(nums.begin(),nums.end());
st=vector<bool>(nums.size());
path=vector<int>(nums.size());
dfs(nums,0,0); // 枚举nusm中第u个数放在path中的位置,要是u和u-1数字一样,我们把u放在第u-1个数后面,dfs新加一个参数。
return res;
}
void dfs(vector<int>&nums,int u,int up_u)
{
if(u==nums.size())
{
res.push_back(path);
return ;
}
if(!u || nums[u-1] != nums[u]) up_u=0;
for(int i=up_u;i<nums.size();i++)
{
if(st[i]==false)
{
st[i]=true;
path[i]=nums[u];
dfs(nums,u+1,i);
st[i]=false;
}
}
}
};
复杂链表的复刻
/**
* Definition for singly-linked list with a random pointer.
* struct ListNode {
* int val;
* ListNode *next, *random;
* ListNode(int x) : val(x), next(NULL), random(NULL) {}
* };
*/
class Solution {
public:
ListNode *copyRandomList(ListNode *head) {
ListNode * p;
for(p=head;p;)
{
auto t=p->next;
auto np = new ListNode(p->val);
p->next=np;
np->next=t;
p=t;
}
for(p=head;p; p=p->next->next)
{
if(p->random)
{
p->next->random = p->random->next;
}
}
ListNode * res = new ListNode(-1);
ListNode *q=res;
for(p=head;p;p=p->next)
{
q->next=p->next;
q=q->next;
p->next = p->next->next;
}
return res->next;
}
};
二叉搜索树与双向链表
写法
dfs返回一个pair类型,表示子树的区间,dfs过程中分四种情况
- 没有左子树&&没有右子树:返回{root,root}
- 有左子树 &&没有右子树:返回{root,right.second}
- 没有左子树&&有右子树: 返回{left.first,root}
- 有左子树&&有右子树: 返回{left.first,right.second}
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* convert(TreeNode* root) {
if(!root) return NULL;
auto left=dfs(root);
return left.first;
}
pair<TreeNode * ,TreeNode*> dfs(TreeNode *root)
{
if(!root->left && !root->right) return {root,root};
if(root->left && root->right)
{
auto left=dfs(root->left);
auto right=dfs(root->right);
left.second->right=root,root->left=left.second;
right.first->left=root,root->right=right.first;
return make_pair(left.first,right.second);
}
else if(root->left && !root->right)
{
auto left=dfs(root->left);
left.second->right=root,root->left=left.second;
return make_pair(left.first,root);
}
else{
auto right=dfs(root->right);
right.first->left=root,root->right=right.first;
return make_pair(root,right.second);
}
}
};
序列化二叉树
class Solution {
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
string res;
dfs_s(root, res);
return res;
}
void dfs_s(TreeNode *root, string &res)
{
if (!root) {
res += "null ";
return;
}
res += to_string(root->val) + ' ';
dfs_s(root->left, res);
dfs_s(root->right, res);
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
int u = 0;
return dfs_d(data, u);
}
TreeNode* dfs_d(string data, int &u)
{
if (u == data.size()) return NULL;
int k = u;
while (data[k] != ' ') k ++ ;
if (data[u] == 'n') {
u = k + 1;
return NULL;
}
int val = 0, sign = 1;
if (u < k && data[u] == '-') sign = -1, u ++ ;
for (int i = u; i < k; i ++ ) val = val * 10 + data[i] - '0';
val *= sign;
u = k + 1;
auto root = new TreeNode(val);
root->left = dfs_d(data, u);
root->right = dfs_d(data, u);
return root;
}
};
整数中1的个数
分类讨论
aaaxbbb
aaa为0-aaa-1,一共有多少种
aaa为aaa,分为俩种,一种是x为1,一种x大于1
class Solution {
public:
int numberOf1Between1AndN_Solution(int n) {
if(!n) return 0;
vector<int>nums;
while(n)
{
nums.push_back(n%10);
n/=10;
}
int res=0;
for(int i=nums.size()-1;i>=0;i--)
{
int x=nums[i];
if(i<nums.size()-1)
{
res+=get_num(nums,nums.size()-1,i+1)*get10(i);
}
if(x==1) res+=1+get_num(nums,i-1,0);
if(x>1) res+=get10(i);
}
return res;
}
int get_num(vector<int>nums,int l,int r)
{
int res=0;
for(int i=l;i>=r;i--)
res=res*10+nums[i];
return res;
}
int get10(int x)
{
int res=1;
while(x--)
{
res*=10;
}
return res;
}
};