@LIUHUAN
2019-12-29T09:41:34.000000Z
字数 14570
阅读 1834
algorithm
int findLengthOfLCIS(vector<int>& nums) {int n = nums.size();if(n <= 1)return n;int maxlen = 1;for(int i = 0; i < n;i++ ) {int len = 1;// 每次nums[i] 开始的序列最大长度为1,往后增长for(int j = i+ 1;j < n;j++){if(nums[j] > nums[j-1] ) {// 连续递增len += 1; // 长度增加maxlen = max(maxlen,len);}else {// 不连续递增了,下一个元素继续计算break;}}return maxlen;}
int findLengthOfLCIS(vector<int>& nums) {int n = nums.size();if(n <= 1)return n;vector<int> dp(n,1);int maxlen = 1;for(int i = 1; i < n; i++ ) {if( nums[i] > nums[i-1] ) {dp[i] = dp[i-1] + 1 ;}maxlen = max( dp[i] , maxlen );}return maxlen;}
int lengthOfLIS(vector<int>& nums) {int n = nums.size();if(n <= 1 )return n;vector<int> dp(n,1);// 初始化为1int max_len = 1;for(int i = 1 ;i < n; i++) {for(int j = i-1 ;j >=0 ;j-- ) { // 遍历[0,i-1]的元素加上nums[i] 之后的长度是否构成更长的递增子序列if(nums[j] < nums[i]) {dp[i] = max(dp[i],dp[j] + 1 );max_len = max(max_len,dp[i]);}}}return max_len;}
int findNumberOfLIS(vector<int>& nums) {int n = nums.size();if(n <= 1)return n;vector<int> dp(n,1); // nums[i]结尾的最长递增子序列长度int max_len = 1;//最大长度vector<int> max_c(n,1);// 每个最长子序列的长度默认为1for(int i = 1; i < n; i++ ){for(int j = i - 1; j >= 0; j-- ) {if(nums[i] > nums[j]) {if(dp[i] < dp[j] + 1){// dp[i] 可以从dp[j] 扩展得到更长的子序列,那么最长子序列的个数就是扩展前dp[j]的个数,max_c[j]max_c[i] = max_c[j]; // 扩展后的来源个数}else if(dp[i] == dp[j] + 1) { // 相同长度的其他扩展而来的子序列max_c[i] += max_c[j] ; // 因为长度相同,所以求和来源的个数}dp[i] = max(dp[i],dp[j] + 1);max_len = max(dp[i],max_len);}}}// 遍历所有的dp[i]等于最大长度时,求和所有的max_c[i],得到最大长度递增子序列的个数和int maxc = 0;for(int i = 0; i < n ; i++) {if(dp[i] == max_len) {maxc += max_c[i];}}return maxc;}
int findLongestChain(vector<vector<int>>& pairs) {int n = pairs.size();if(n <= 1)return n;sort(pairs.begin(),pairs.end(),[](vector<int>& a,vector<int>&b ){return a[0] < b[0];});vector<int> dp(n,1);int max_len = 1;for(int i =1;i < n; i++) {int ifirst = pairs[i][0];for(int j =i -1 ;j >= 0; j--) {if(pairs[j][1] < ifirst) { // 构成递增链dp[i] = max(dp[i],dp[j] + 1); //更新递增链大小max_len = max(max_len,dp[i]);}}}return max_len;}
int numberOfArithmeticSlices(vector<int>& A) {int n = A.size();if(n <= 2 )return 0;vector<vector<int> > dp(n,vector<int>(n,0));for(int i = 1; i < n-1; i++) {dp[i-1][i+1] = (A[i] -A[i-1] == A[i+1] -A[i] );}for(int k = 3; k < n ;k++ ) {for(int i = 0; i < n; i++ ) {int j = i + k;if(j >= n)break;dp[i][j] = dp[i][j-1] && (A[j] - A[j-1] == A[j-1] - A[j-2]);}}int c = 0;for(int i =0 ;i < n; i++) {for(int j = i+2;j < n; j++) {if(dp[i][j] == 1)c += 1;}}return c;}
int longestArithSeqLength(vector<int>& A) {int n = A.size();vector<vector<int>> dp(n,vector<int>(n,2));for(int i = 0; i < n; i++ ) {dp[i][i] = 0;}int maxlen = 2;for(int i = 1; i < n; i++ ) {for(int j = i + 1; j <n ; j++) {int ak = 2*A[i] - A[j]; // 查找A[j] - A[i] == A[i] - A[k]for(int k = 0; k < i ;k++) {if(A[k] == ak) {dp[i][j] = max(dp[i][j] , dp[k][i] + 1 );maxlen = max(dp[i][j],maxlen);}}}}return maxlen;}
int numberOfArithmeticSlices(vector<int>& A) {int n = A.size();vector<vector<int>> dp(n,vector<int>(n,0));int sum = 0;for(int i = 0; i < n; i++ ) {for(int j = i + 1; j < n; j++ ) {// int ak = 2*A[i] - A[j]; // mind overflow !!!long t = A[j];t -= A[i];for(int k = 0; k < i; k++ ) {long x = A[i];x -= A[k];if(t == x ) {dp[i][j] += dp[k][i] + 1;}}sum += dp[i][j];}}return sum;}
int getMoneyAmount(int n) {vector<vector<int>> dp(n+1,vector<int>(n+1,INT_MAX));// 默认最大代价for(int i = 1;i < n ; i++) {dp[i][i+1] = i; // 初始情况步长为1dp[i][i] = 0;}dp[0][0] = 0;dp[n][n] = 0;int k = 2;// 步长为2for(int k =2 ;k <= n; k++ ) {for(int i = 1;i <= n; i++) {int j = i + k;// [i,j]范围内if(j > n)break;int mincost = INT_MAX;for(int m = i+1; m < j;m++) { // [i,m-1],[m+1,j]int t = max(dp[i][m-1],dp[m+1][j]) + m; // 选择猜测m,之后的最保险策略(能够猜到候选数的最大代价,付出这个代价,无论第二步,第三步,怎么猜测,一定能够找到候选数)mincost = min(mincost,t); // 选择一个最小,最为[i,j]的猜测代价}dp[i][j] = mincost;}}return dp[1][n]; // 返回[1,n]最小代价}
bool PredictTheWinner(vector<int>& nums) {int n = nums.size();vector<vector<int>> dp(n,vector<int>(n,0));int sum = 0;for( int i = 0; i < n; i++ ) {dp[i][i] = nums[i];sum += nums[i];}for( int k = 1; k < n; k++ ) {for( int i = 0; i < n; i++ ) {int j = i + k ;if(j >= n )break;int ni = min(getij (dp,i+1,j-1),getij(dp,i+2,j)) + nums[i];int nj = min(getij(dp,i+1,j-1),getij(dp,i,j-2)) + nums[j];dp[i][j] = max( ni ,nj );}}return dp[0][n-1] >= sum - dp[0][n-1];}int getij(vector<vector<int>>& dp,int i,int j) {int n = dp.size();if( i >= n || j >= n || i < 0 || j < 0 || i > j )return 0;return dp[i][j];}
bool stoneGame(vector<int>& piles) {int m = piles.size();// int n = piles[0].size();vector<vector<int>> dp(m,vector<int>(m,0));int sum = 0;for(int i = 0 ;i < m ;i++) {sum += piles[i];}for(int k = 1; k < m ;k+=2) {for(int i = 0 ;i < m;i++) {int j = i + k ;if(j >= m)break;int front = piles[i] + max(getij(dp,i+1,j-1),getij(dp,i+2,j) );int end = piles[j] + max(getij(dp,i,j-2) , getij(dp,i+1,j-1) );dp[i][j] = max(front,end);}}return sum - dp[0][m-1] < dp[0][m-1];}int getij(vector<vector<int>>& dp,int i ,int j){int m = dp.size();if(i < 0 || j >= m || i >= m || j < 0)return 0;return dp[i][j];}
int numSquares(int n) {if(n <= 0)return 0;if(n == 1)return 1;vector<int> dp(n+1,0);dp[1] = 1;for(int i = 2;i <= n; i++ ) {int m = int(sqrt(i)); // 不会超过这int t = INT_MAX;for(int k = 1 ;k <= m;k++){ // 从1开始遍历int j = k * k;t = min(dp[i-j] +1 ,t);//最小值}dp[i] = t;}return dp[n];}
// n^3int lenLongestFibSubseq(vector<int>& A) {int n = A.size();vector<vector<int>> dp(n,vector<int>(n,2));// 除自己与自己外,所有的序列长度默认为2int maxlen = 0;for(int i = 0; i < n; i++ ) {dp[i][i] = 0; // 自己与自己构成的序列长度设置为0for(int j = i + 1; j< n; j++ ) { // (A[i],A[j])for(int k = 0; k < i; k++ ) { // 对k执行搜索,0<= k < iif(A[i] + A[k] == A[j]) { // A[j] 与(A[k],A[i])可以构成更长的序列dp[i][j] = max(dp[i][j],dp[k][i] + 1);maxlen = max(maxlen,dp[i][j]);}}}}return maxlen;}
lower_bound函数,可以在返回值中判断是否存在
int lenLongestFibSubseq(vector<int>& A) {int n = A.size();vector<vector<int>> dp(n,vector<int>(n,2));int t,maxlen = 0;for(int i = 0;i < n; i++) {dp[i][i] = 0;for(int j = i+1; j< n; j++) {int ak = A[j] - A[i];auto loc = lower_bound(A.begin(),A.begin() + i,ak); // 查找A[k]if(*loc == ak) {int k = loc - A.begin();dp[i][j] = max(dp[i][j],dp[k][i] + 1);maxlen = max(maxlen,dp[i][j]);}}}return maxlen;}
int lenLongestFibSubseq(vector<int>& A) {int n = A.size();vector<vector<int>> dp(n,vector<int>(n,2));int t,maxlen = 0;unordered_map<int,int> umap;for(int i = 0; i < n; i++ ) {umap[A[i]] = i; // 存储所有的值与下标dp[i][i] = 0;}for(int i = 0;i < n; i++) {for(int j = i + 1; j< n; j++) {int ak = A[j] - A[i];auto e = umap.find(ak); // 查找A[k]if(e != umap.end() && e->second < i ) { // be careful the e->second < iint k = e->second;dp[i][j] = max(dp[i][j], dp[k][i] + 1);maxlen = max(maxlen, dp[i][j]);}}}return maxlen;}
int wiggleMaxLength(vector<int>& nums) {int n = nums.size();if(n <= 0)return 0;vector<vector<int>> dp(n,vector<int>());for(int i = 0 ;i < n; i++ ) {dp[i] = {1,1};}int maxlen = 1;for( int i = 1; i < n; i++ ) {for( int j = i - 1; j >=0; j-- ) {if(nums[j] > nums[i]) { // 构成上摆数组dp[i][1] = max(dp[i][1] ,dp[j][0] + 1);}else if( nums[j] < nums[i] ) { // 构成下摆数组dp[i][0] = max(dp[i][0] ,dp[j][1] + 1);}maxlen = max(maxlen,dp[i][0]);maxlen = max(maxlen,dp[i][1]);}}return maxlen;}
int maxProduct(vector<int>& nums) {int n = nums.size();vector<vector<int>> dp(n,vector<int>());if( n <=0 )return 0;for(int i = 0; i < n; i++ ) {dp[i] = {nums[i],nums[i]};}int maxv = nums[0];for(int i = 1; i < n; i++ ) {int a = nums[i];if( a < 0) {dp[i][0] = max(dp[i-1][1] * a ,a);dp[i][1] = min(dp[i-1][0] * a, a);}else if( a > 0) {dp[i][0] = max(dp[i-1][0] * a, a);dp[i][1] = min(dp[i-1][1] * a, a);}maxv = max(maxv,dp[i][0]);}return maxv;}