剑指 Offer II 080. 含有 k 个元素的组合
vector<vector<int>> res;
vector<vector<int>> combine(int n, int k) {
vector<int> xx;
dfs(n,k,1,xx);
return res;
}
void dfs(int n,int k,int idx,vector<int> xx){
if(xx.size()==k){
res.push_back(xx);
return ;
}
for(int i=idx;i<=n;i++){
xx.push_back(i);
dfs(n,k,i+1,xx);
xx.pop_back();
}
}
剑指 Offer II 081. 允许重复选择元素的组合
vector<vector<int>> res;
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<int> xx;
dfs(0,0,target,candidates,xx);
return res;
}
void dfs(int sum,int idx,int target,vector<int> nums,vector<int> recode){
if(sum>target) return ;
if(sum==target){
res.push_back(recode);
return ;
}
for(int i=idx;i<nums.size();i++){
sum+=nums[i];
recode.push_back(nums[i]);
dfs(sum,i,target,nums,recode);
recode.pop_back();
sum-=nums[i];
}
}
剑指 Offer II 082. 含有重复元素集合的组合
vector<bool> st;
vector<vector<int>> res;
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
for(int i=0;i<candidates.size();i++) st.push_back(false);
sort(candidates.begin(),candidates.end());
vector<int> xx;
dfs(0,0,target,candidates,xx);
return res;
}
void dfs(int sum,int idx,int target,vector<int> nums,vector<int> recode){
if(sum>target) return ;
if(sum==target){
res.push_back(recode);
return ;
}
for(int i=idx;i<nums.size();i++){
if(i&&nums[i]==nums[i-1]&&!st[i-1]) continue;
st[i]=true;
sum+=nums[i];
recode.push_back(nums[i]);
dfs(sum,i+1,target,nums,recode);
recode.pop_back();
sum-=nums[i];
st[i]=false;
}
}
剑指 Offer II 083. 没有重复元素集合的全排列
vector<vector<int>> res;
vector<bool> st;
int n=0;
vector<vector<int>> permute(vector<int>& nums) {
n=nums.size();
for(int i=0;i<n;i++) st.push_back(false);
vector<int> xx;
dfs(0,xx,nums);
return res;
}
void dfs(int idx,vector<int> xx,vector<int> nums){
if(xx.size()==n){
res.push_back(xx);
return ;
}
for(int i=0;i<nums.size();i++){
if(st[i]) continue;
st[i]=true;
xx.push_back(nums[i]);
dfs(i,xx,nums);
xx.pop_back();
st[i]=false;
}
}
剑指 Offer II 084. 含有重复元素集合的全排列
vector<vector<int>> res;
vector<bool> st;
int n=0;
vector<vector<int>> permuteUnique(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<int>xx;
n=nums.size();
for(int i=0;i<n;i++) st.push_back(false);
dfs(0,xx,nums);
return res;
}
void dfs(int idx,vector<int> xx,vector<int> nums){
if(xx.size()==n){
res.push_back(xx);
return ;
}
for(int i=0;i<nums.size();i++){
if(st[i]) continue;
if(i&&!st[i-1]&&nums[i]==nums[i-1]) continue;
st[i]=true;
xx.push_back(nums[i]);
dfs(i,xx,nums);
xx.pop_back();
st[i]=false;
}
}
剑指 Offer II 085. 生成匹配的括号
string m="()";
vector<string> res;
vector<string> ans;
vector<string> generateParenthesis(int n) {
string xx;
dfs(n,xx);
for(int i=0;i<res.size();i++){
int cnt=0;
int tt=0;
bool flag=true;
for(int j=0;j<res[i].size();j++){
if(res[i][j]==')'){
if(tt) tt--;
else {
flag=false;
break;
}
}
else tt++;
}
if(flag&&tt==0) ans.push_back(res[i]);
}
return ans;
}
void dfs(int n,string xx){
if(xx.size()==n*2){
res.push_back(xx);
return ;
}
for(int i=0;i<2;i++){
xx.push_back(m[i]);
dfs(n,xx);
xx.pop_back();
}
}
剑指 Offer II 086. 分割回文子字符串
vector<vector<string>> res;
int n;
bool f[16][16];
vector<vector<string>> partition(string s) {
n=s.size();
memset(f,0,sizeof(f));
vector<string> xx;
for(int i=n;i>=0;i--){
for(int j=i;j<n;j++){
if(i==j) f[i][j]=1;
if(j==i+1&&s[i]==s[j]) f[i][j]=1;
if(j-i>1&&f[i+1][j-1]&&s[i]==s[j]) f[i][j]=1;
}
}
dfs(0,s,xx);
return res;
}
void dfs(int idx, string s,vector<string> xx){
if(idx==s.size()){
res.push_back(xx);
return ;
}
for(int i=idx;i<n;i++){
if(f[idx][i]){
xx.push_back(s.substr(idx,i-idx+1));
dfs(i+1,s,xx);
xx.pop_back();
}
}
}
剑指 Offer II 087. 复原 IP
vector<string> res;
vector<string> restoreIpAddresses(string s) {
string xx;
dfs(0,s,xx);
return res;
}
void dfs(int idx,string s,string xx){
if(idx==s.size()&&count(xx.begin(),xx.end(),'.')==4){
xx.pop_back();
res.push_back(xx);
return ;
}
if(idx>=s.size()||count(xx.begin(),xx.end(),'.')>=4) return;
for(int len=1;len<=3;len++){
string str=s.substr(idx,len);
if(atoi(str.c_str())>255) continue;
if(str.size()>1&&str[0]=='0') continue;
string ori=xx;
xx+=str+'.';
dfs(idx+len,s,xx);
xx=ori;
}
}
剑指 Offer II 088. 爬楼梯的最少成本
int minCostClimbingStairs(vector<int>& cost) {
int f[cost.size()+1];
memset(f,0,sizeof(f));
f[0]=0;
f[1]=0;
for(int i=2;i<=cost.size();i++){
f[i]=min(f[i-1]+cost[i-1],f[i-2]+cost[i-2]);
}
return f[cost.size()];
}
剑指 Offer II 089. 房屋偷盗
int rob(vector<int>& nums) {
if(nums.size()==1) return nums[0];
int f[nums.size()];
memset(f,0,sizeof(f));
f[0]=nums[0];f[1]=nums[1];
for(int i=0;i<nums.size();i++){
for(int j=i-2;j>=0;j--){
f[i]=max(f[i],f[j]+nums[i]);
}
}
return max(f[nums.size()-1],f[nums.size()-2]);
}
剑指 Offer II 090. 环形房屋偷盗
int rob(vector<int> nums,int start,int end){
if(start==end) return nums[start];
int f[nums.size()];
memset(f,0,sizeof(f));
f[start]=nums[start];f[start+1]=nums[start+1];
for(int i=start+2;i<=end;i++){
for(int j=start;j<=i-2;j++){
// cout<<i<<" "<<j<<" "<<start<<" "<<end<<endl;
f[i]=max(f[i],f[j]+nums[i]);
}
}
// int xx=f[end];
//cout<<xx<<endl;
// if(end-1>=start) xx=max(xx,f[end-1]); cout<<xx<<endl;
return max(f[end],f[end-1]);
}
int rob(vector<int>& nums) {
if(nums.size()==0) return 0;
if(nums.size()==1) return nums[0];
return max(rob(nums,0,nums.size()-2),rob(nums,1,nums.size()-1));
}
剑指 Offer II 091. 粉刷房子
int minCost(vector<vector<int>>& costs) {
int n=costs.size();
int f[n][3];
memset(f,0,sizeof(f));
f[0][0]=costs[0][0];
f[0][1]=costs[0][1];
f[0][2]=costs[0][2];
for(int i=1;i<n;i++){
f[i][0]=min(f[i-1][1],f[i-1][2])+costs[i][0];
f[i][1]=min(f[i-1][0],f[i-1][2])+costs[i][1];
f[i][2]=min(f[i-1][0],f[i-1][1])+costs[i][2];
}
return min(min(f[n-1][0],f[n-1][1]),f[n-1][2]);
}
剑指 Offer II 092. 翻转字符
int minFlipsMonoIncr(string s) {
int f[s.size()];
memset(f,0,sizeof(f));
if(s[0]=='1') f[0]=1;
for(int i=1;i<s.size();i++){
if(s[i]=='1') f[i]=f[i-1]+1;
else f[i]=f[i-1];
}
int n=s.size();
int res=INT_MAX;
for(int i=0;i<n;i++){
int one=0,zero=0;
if(i==0){
one=0;
zero=n-1-(f[n-1]-f[0]);
}else if(i==n-1){
zero==0;
one=f[n-2];
}else{
one=f[i-1];
zero=n-(i+1)-(f[n-1]-f[i]);
}
res=min(res,one+zero);
}
return res;
}
剑指 Offer II 093. 最长斐波那契数列
int lenLongestFibSubseq(vector<int>& arr) {
int n=arr.size();
unordered_map<int ,int >map;
for(int i=0;i<n;i++) map[arr[i]]=i;
vector<vector<int>> f(n,vector<int>(n));
int res=0;
for(int i=0;i<n;i++){
for(int j=0;j<i;j++){
int x=arr[i]-arr[j];
f[j][i]=2;
if(map.count(x)&&x<arr[j]){
int k=map[x];
f[j][i]=max(f[j][i],f[k][j]+1);
res=max(res,f[j][i]);
}
}
}
if(res<3) return 0;
return res;
}
剑指 Offer II 094. 最少回文分割
int minCut(string s) {
s=' '+s;
int n=s.size();
int f[n];
memset(f,0,sizeof(f));
vector<vector<bool>> st(n,vector<bool>(n));
for(int j=n-1;j>=1;j--){
for(int i=j;i<n;i++){
if(i==j) st[j][i]=true;
if(i-j==1&&s[i]==s[j]) st[j][i]=true;
if(i-j>1&&s[i]==s[j]&&st[j+1][i-1]) st[j][i]=true;
}
}
f[0]=0;
for(int i=1;i<n;i++){
f[i]=INT_MAX;
if(st[1][i]) {
f[i]=0;
continue;
}
for(int j=1;j<=i;j++){
if(st[j][i]) f[i]=min(f[i],f[j-1]+1);
}
}
return f[n-1];
}
剑指 Offer II 095. 最长公共子序列
int longestCommonSubsequence(string text1, string text2) {
int f[text1.size()+1][text2.size()+1];
memset(f,0,sizeof(f));
for(int i=1;i<=text1.size();i++){
for(int j=1;j<=text2.size();j++){
if(text1[i-1]==text2[j-1]) f[i][j]=max(f[i][j],f[i-1][j-1]+1);
else f[i][j]=max(f[i-1][j],f[i][j-1]);
}
}
return f[text1.size()][text2.size()];
}
剑指 Offer II 096. 字符串交织
bool isInterleave(string s1, string s2, string s3) {
if(s1.size()+s2.size()!=s3.size()) return false;
int n=s1.size(),m=s2.size();
s1=" "+s1,s2=" "+s2,s3=" "+s3;
vector<vector<bool>> f(n+1,vector<bool> (m+1));
f[0][0]=true;
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
if(i&&s1[i]==s3[i+j]) f[i][j]=f[i-1][j];
if(j&&s2[j]==s3[i+j]) f[i][j]=f[i][j-1]||f[i][j];
}cout<<endl;
}
return f[n][m];
}
剑指 Offer II 097. 子序列的数目
int numDistinct(string s, string t) {
if(s.size()==0||t.size()==0||s.size()<t.size()) return 0;
int n=s.size(),m=t.size();
s=" "+s,t=" "+t;
vector<unsigned long long > f(m+1);
f[0]=1;
for(int i=1;i<=n;i++){
for(int j=m;j>=0;j--){
// f[j]+=f[j];
if(s[i]==t[j]&&j) f[j]+=f[j-1];
}
}
return f[m];
}
剑指 Offer II 098. 路径的数目
int uniquePaths(int m, int n) {
int f[m][n];
memset(f,0,sizeof(f));
for(int i=0;i<m;i++) f[i][0]=1;
for(int i=0;i<n;i++) f[0][i]=1;
for(int i=0;i<m;i++){
for(int k=0;k<n;k++){
if(i&&k) f[i][k]=f[i-1][k]+f[i][k-1];
}
}
return f[m-1][n-1];
}
剑指 Offer II 099. 最小路径之和
int minPathSum(vector<vector<int>>& grid) {
int n=grid.size(),m=grid[0].size();
int f[n][m];
memset(f,0,sizeof(f));
f[0][0]=grid[0][0];
for(int i=1;i<n;i++) f[i][0]=f[i-1][0]+grid[i][0];
for(int i=1;i<m;i++) f[0][i]=f[0][i-1]+grid[0][i];
for(int i=1;i<n;i++){
for(int j=1;j<m;j++){
f[i][j]=min(f[i-1][j],f[i][j-1])+grid[i][j];
}
}
return f[n-1][m-1];
}
剑指 Offer II 100. 三角形中最小路径之和
int minimumTotal(vector<vector<int>>& triangle) {
if(triangle.size()==1) return triangle[0][0];
int n=triangle.size(),m=n;
int f[m];
memset(f,0,sizeof(f));
f[0]=triangle[0][0];
int res=INT_MAX;
for(int i=1;i<n;i++){
for(int j=i;j>=0;j--){
if(j!=i) f[j]=f[j]+triangle[i][j];
else f[j]=f[j-1]+triangle[i][j];
if(j) f[j]=min(f[j],f[j-1]+triangle[i][j]);
if(i==n-1) res=min(res,f[j]);
}
}
return res;
}