# leetccode编程笔记（3）

### 1 数组中重复的数据

输入:
[4,3,2,7,8,2,3,1]

[2,3]

class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
int len = nums.size();
int *a = (int*)calloc(len+1,sizeof(int));
vector<int> res;
for(int num:nums)
{
a[num]+=1; //将遍历的数作为数组下标进行统计
if(a[num]>=2) res.push_back(num);
}
free(a);
return res;
}
};

7 3 2 4 8 2 3 1
3 3 2 4 8 2 7 1
2 3 3 4 8 2 7 1
3 2 3 4 8 2 7 1
3 2 3 4 1 2 7 8
1 2 3 4 3 2 7 8

class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
int len = nums.size();
vector<int> res;
int tmp;
for(int i=0;i<len;++i)
{
while(nums[i]!=nums[nums[i]-1])//这个while实际执行次数很小，所以时间复杂度按外层计算
{
tmp=nums[i];
nums[i]=nums[tmp-1];
nums[tmp-1]=tmp;
}
}
for(int i=0;i<len;++i)
{
if(nums[i]!=i+1)
res.push_back(nums[i]);
}
return res;
}
};

### 2 合并两个有序链表

输入：1->2->4, 1->3->4

/**
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(!l1) return l2;
if(!l2) return l1;//判断是否为空
if(l1->val<=l2->val)//先将小的链表头拿出来作为要合并的头
{
s=l1;
l1=l1->next;
s->next=NULL;
}
else
{
s=l2;
l2=l2->next;
s->next=NULL;
}
while(l1&&l2)//遍历链表，谁小接谁
{
if(l1->val<=l2->val)
{
s->next=l1;
l1=l1->next;
}
else
{
s->next=l2;
l2=l2->next;
}
s=s->next;
s->next=NULL;
}
if(!l1)//遍历完将剩下的另一个接后面
s->next=l2;
if(!l2)
s->next=l1;
}
};

### 3 路径总和 II

              5
/ \
4   8
/   / \
11  13  4
/  \    / \
7    2  5   1


[
[5,4,11,2],
[5,8,4,5]
]
/**
* 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:
vector<vector<int>> res;
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<int> path;//用于保存搜索路径，遍历与回溯
findPath(root,path,sum,0);
return res;
}
void findPath(TreeNode*root,vector<int> path,int sum,int cursum)
{
if(root==NULL) return;
cursum+=root->val;//将当前节点的值累加并加入路径
path.push_back(root->val);

bool isleaf=root->left==NULL&&root->right==NULL;
if(cursum==sum&&isleaf)//累加值等于要求的值，并且是叶子节点，则保存当前路径
res.push_back(path);
//先序遍历
if(root->left!=NULL)
findPath(root->left,path,sum,cursum);
if(root->right!=NULL)
findPath(root->right,path,sum,cursum);

path.pop_back();//回溯到上一层
}
};