# 数据结构与算法-5大常用算法总结

### 1.贪心算法

#### 1.1简单的作业调度问题

vector<int> findCompleteWorkCount(vector<int> start, vector<int> finish)
{
vector<int> result;
int i = 0;
for (int j = 1; j < start.size(); ++j)
{
if (start[j] >= finish[i])
{
result.push_back(j);
i = j;
}
}
return result;
}

#### 1.2最小生成树prim算法

#define v 5
void printMST(int parent[], int graph[v][v])
{
printf("Edge   Weight\n");
for (int i = 1; i < v; i++)
printf("%d - %d    %d \n", parent[i], i, graph[i][parent[i]]);
}
void prim(int graph[v][v])
{
int value[v];
bool finish[v];
int parent[v];
for (int i = 1; i < v; ++i)
{
value[i] = graph[0][i];
parent[i] = 0;
finish[i] = false;
}
parent[0] = -1;
finish[0] = true;
for (int i = 1; i < v; ++i)
{
int min_val = INT_MAX, min_index;
for (int j = 1; j<v; ++j)
if (!finish[j] && value[j] != 0 && value[j] < min_val)
{
min_val = value[j];
min_index = j;
}
finish[min_index] = true;
for (int j = 1; j < v; ++j)
if (!finish[j] && graph[min_index][j]!=0&&(value[j] == 0 || graph[min_index][j] < value[j]))
{
parent[j] = min_index;
value[j] = graph[min_index][j];
}
}
printMST(parent, graph);
}

### 2.分治算法

#### 2.1最大字数组问题

int Start,End,Value;
int FindMaxCrossArray(int a[],int low,int mid,int high)
{
int left_sum=numeric_limits<int>::min();
int right_sum=numeric_limits<int>::min();
int sum=0;

for (int i=mid;i>=low;i--)
{
sum+=a[i];
if(sum>left_sum)
{
left_sum=sum;
Start=i;
}
}
sum=0;
for(int j=mid+1;j<=high;j++)
{
sum+=a[j];
if (sum>right_sum)
{
right_sum=sum;
End=j;
}
}
return left_sum+right_sum;
}
int FindMaxArray(int a[],int low,int high)
{
if (low==high)
{
Start=End=low;
return a[low];
}
int mid=(low+high)/2;
int left_sum=FindMaxArray(a,low,mid);
int right_sum=FindMaxArray(a,mid+1,high);
int cross_sum=FindMaxCrossArray(a,low,mid,high);
if (left_sum>=right_sum&&left_sum>=cross_sum)
{
Start=low;
End=mid;
return left_sum;
}
else if (right_sum>=left_sum&&right_sum>=cross_sum)
{
Start=mid+1;
End=high;
return right_sum;
}
else
return cross_sum;

}
int main()
{
int a[13]={-13,-3,-25,-20,-3,-16,-23,-18,-20,-7,-12,-5,-22};
int result=FindMaxArray(a,0,12);
return 0;
}

### 3.动态规划

#### 3.1背包问题

int Max(int a,int b)
{
return a>b?a:b;
}
int main()
{

int N,i,j;
int p[100][100];
int C;
vector<Goods> goods;
cout<<"请输入商品总量";
cin>>N;
for (i=0;i<N;i++)
{
cout<<"请输入第"<<i+1<<"个的价值和重量:";
int vi,wi;
cin>>vi>>wi;
goods.push_back(Goods(vi,wi));
}
cout<<"请输入背包最大重量";
cin>>C;
for (i=0;i<N;i++)
p[i][0]=0;
for (j=0;j<C;j++)
p[0][j]=0;
for (i=1;i<N;i++)
for (j=1;j<C;j++)
{
if(j<goods[i].w)p[i][j]=p[i-1][j];
else
p[i][j]=Max(p[i-1][j-goods[i].w]+goods[i].v,p[i-1][j]);
}
return 0;
}

#### 3.2leetcode动态规划题目

1. Minimum Path Sum
int minPathSum(vector<vector<int>>& grid) {
if (grid.empty())return 0;
vector<vector<int>> result(grid);
for (int i = 1; i < result[0].size(); ++i)
result[0][i] += result[i][i - 1];
for (int i = 1; i < result.size(); ++i)
result[i][0] += result[i-1][0];

for (int i = 1; i > result.size(); ++i)
for (int j = 1; j < result[i].size(); ++j)
result[i][j] = min(result[i - 1][j] + grid[i][j], result[i][j - 1] + grid[i][j]);

return result[result.size() - 1][result[0].size() - 1];
}

### 4.回溯算法

（1）针对所给问题，确定问题的解空间：首先应明确定义问题的解空间，问题的解空间应至少包含问题的一个（最优）解。
（2）确定结点的扩展搜索规则
（3）以深度优先方式搜索解空间，并在搜索过程中用剪枝函数避免无效搜索。

#### 4.1leetcode相关题目

1. Combination Sum
class Solution {
public:
vector<vector<int>> result;
vector<int> data;
int sum(const vector<int>& v)
{
int sum = 0;
for (auto e : v)sum += e;
return sum;
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {

vector<int> temp;
sort(candidates.begin(), candidates.end());
data = candidates;
dfs(temp, target, 0);
return result;
}
void dfs(vector<int> temp, int target, int k)
{
if (k == data.size())return;
if (sum(temp) == target) {
result.push_back(temp); return;}
else if (sum(temp) > target)return;
else
{
for (int i = k; i < data.size(); ++i)
{
temp.push_back(data[i]);
dfs(temp, target, i);
temp.pop_back();
}
}
}
};

2.Subsets

class Solution {
public:
vector<vector<int>> result;
vector<int> temp;
vector<vector<int>> subsets(vector<int>& nums) {
dfs(nums, 0, nums.size() - 1);
return result;
}
void dfs(vector<int> nums, int i, int j)
{
result.push_back(temp);
for (int k = i; k <=j; ++k)
{
temp.push_back(nums[k]);
dfs(nums, k + 1, j);
temp.pop_back();
}
}
};

3.Permutations