357. Count Numbers with Unique Digits

解题思路:

用arr[i]存放长度为i时,各位互不相同的数字的个数,所以arr[1]=10,arr[2]=9*9。(第一位要为1,第二位与第一位要不同)

arr[3] = arr[2]*8,所以arr[i]=arr[i-1]*(10 - (k-1))。之后求和就可以了。

int countNumbersWithUniqueDigits(int n) {
if (!n)
return 1;
if (n == 1)
return 10;
if (n == 2)
return 91;
int sum = 0;
int arr[n + 2];
arr[1] = 10;
arr[2] = 81;
for (int i = 3; i <= n; i++)
arr[i] = arr[i-1] * (11 - i);
for (int i = 1; i <= n; i++) {
sum += arr[i];
}
return sum;
}

  


5. Longest Palindromic Substring

解题思路:

这道题使用一个数组dp[i][j]存储子串s[i...j]是否为回文串。那么dp[i][i]=true(i = 0...n), dp[i][i-1]=true(i = 1...n)

其他为false。判断的时候,dp[i][j] = (s[i] == s[j] && dp[i+1][j-1] == true)。同时,需要记录最长回文串的位置。

枚举子串时,从k=2开始到n。

string longestPalindrome(string s) {
if (s.length() < 2)
return s;
int left = 0;
int right = 0;
bool dp[s.length()][s.length()];
memset(dp, false, sizeof(dp));
dp[0][0] = true;
for (int i = 1; i < s.length(); i++) {
dp[i][i] = true;
dp[i][i-1] = true;
}
int i, j, k;
for (k = 2; k <= s.length(); k++) {
for (i = 0; i <= s.length() - k; i++) {
j = i - 1 + k;
if (s[i] == s[j] && dp[i+1][j-1] == true) {
dp[i][j] = true;
if (right - left + 1 < k) {
left = i;
right = j;
}
}
}
}
return s.substr(left, right - left + 1);
}

  


516. Longest Palindromic Subsequence

解题思路:

subsequence与substring的区别在于它可以是不连续的,此处的思路是:

用dp[i][j]存储子序列s[i...j]中最长回文串的长度。初始化时,除了dp[i][i]=1外,其它都置为0。

枚举子序列的长度,从2开始。所以如果s[i]==s[j],那么dp[i][j] = dp[i+1][j-1]+2;否则

dp[i][j] = max(dp[i-1][j], dp[i][j-1])。最后只要返回dp[0][n-1]就可以了。

int longestPalindromeSubseq(string s) {
if (s.size() < 2)
return s.size();
int dp[s.size()][s.size()];
for (int i = 0; i < s.size(); i++) {
for (int j = 0; j < s.size(); j++) {
dp[i][j] = 0;
}
dp[i][i] = 1;
}
int i, j, k;
for (k = 1; k < s.size(); k++) {
for (i = 0; i < s.size() - k; i++) {
j = i + k;
if (s[i] == s[j])
dp[i][j] = dp[i+1][j-1] + 2;
else
dp[i][j] = dp[i+1][j] > dp[i][j-1] ? dp[i+1][j] : dp[i][j-1];
}
}
return dp[0][s.size()-1];
}

  


368. Largest Divisible Subset

解题思路:

这道题类似于求最长递增子序列。。考虑的是,大的数整除小的数,所以现将数组排序。然后用dp[i]记录以第i个数结尾的最长可整除子集的长度。

那么状态转移方程为:dp[i] = max{dp[j] + 1},j = 0...i-1。同时,要求dp[j]%dp[i]==0。另外,因为需要记录子集的内容,所以使用另一个

数组set来保留加入的序号(针对nums的),使用max记录最大长度,last记录最后一个序号。

需要注意的是,C++中数组的赋值,不能用int dp[n] = {1},因为这样只将dp[0]赋值为1,其他为0;也不能用memset,很奇怪==

vector<int> largestDivisibleSubset(vector<int>& nums) {
if (nums.size() < 2)
return nums;
// sort
sort(nums.begin(), nums.end());
// this way, only get 1,0,0
//int dp[nums.size()] = {1};
int dp[nums.size()];
// wrong!
//memset(dp, 1, nums.size());
int set[nums.size()];
for (int i = 0; i < nums.size(); i++) {
dp[i] = 1;
set[i] = -1;
}
int max = 0;
int last = -1;
vector<int> result;
for (int i = 1; i < nums.size(); i++) {
for (int j = 0; j < i; j++) {
if (nums[i] % nums[j] == 0 && dp[j] + 1 > dp[i]) {
dp[i] = dp[j] + 1;
set[i] = j;
}
if (dp[i] > max) {
max = dp[i];
last = i;
}
}
}
// get result
for (int i = last; i >= 0;) {
result.insert(result.begin(), nums[i]);
i = set[i];
}
return result;
}

  


494. Target Sum

解题思路:

可以将所有数字分为两个组,positive和negative,那么

positive - negative = target

positive + negative = sum

所以两式相加,2postive = target + sum。所以可以把所有数字变为原来的两倍,选其中一部分数字作为positive,剩下的自然是negative,

看有多少种选法可以使得总和为target+sum。因此使用数组dp[i]来记录总和达到i的方法数。注意:

1) 初始化dp[0] = 1

2) 只考虑j>=nums[i]的情况,而且j要从target开始,不能从0开始,否则会WA

int findTargetSumWays(vector<int>& nums, int S) {
int sum = 0;
for(int i = 0; i < nums.size(); i++) {
sum += nums[i];
nums[i] *= 2;
}
if (sum < S)
return 0;
int target = sum + S;
int dp[target + 1];
// initialize
dp[0] = 1;
for (int i = 0; i < nums.size(); i++) {
// ATTENTION: j
for (int j = target; j >= 0; j--) {
if (j >= nums[i]) {
dp[j] += dp[j - nums[i]];
}
}
}
return dp[target];
}

  


343. Integer Break

解题思路:

首先n=2时返回1,n=3时返回2,这两个需要特别考虑。然后用result[i]存储和为i时乘积最大值,因此

result[i]=max{result[i-3]*3, result[i-2]*2}。而关于result[2]和result[3]的值,需要观察。。

i = 4, max(1*3, 2*2) = 4

i = 5, max(result[2]*3, result[3]*2) = max(2*3, 3*2) = 6

i = 6, max(result[3]*3, result[4]*2) = max(3*3, 4*2) = 9

因此,result[2] = 2, result[3] = 3

int integerBreak(int n) {
int result[n+1] = {0};
if (n <= 3)
return n-1;
result[2] = 2;
result[3] = 3;
for (int i = 4; i <= n; i++) {
result[i] = 3 * result[i-3] > 2 * result[i-2] ? 3 * result[i-3] : 2 * result[i-2];
}
return result[n];
}

 


486. Predict the Winner

https://leetcode.com/problems/predict-the-winner/#/description

简单的说就是两个人轮流抽牌,每个人都可以从头抽或者从尾抽,抽到了就加相应的分数,最后看谁的分高。

解题思路:

用了递归。。

bool PredictTheWinner(vector<int>& nums) {
return myFunc(nums, 0, nums.size()-1) >= 0;
}
int myFunc(vector<int>& nums, int start, int end) {
if (start == end)
return nums[start];
int i = nums[start] - myFunc(nums, start+1, end);
int j = nums[end] - myFunc(nums, start, end-1);
return i > j ? i : j;
}

  

 

leetcode-23-DynamicProgramming-1的更多相关文章

  1. [LeetCode] 23. Merge k Sorted Lists 合并k个有序链表

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. E ...

  2. LeetCode 23. 合并K个排序链表(Merge Two Sorted Lists)

    23. 合并K个排序链表 23. Merge k Sorted Lists 题目描述 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. LeetCode23. Merge k S ...

  3. Java实现 LeetCode 23 合并K个排序链表

    23. 合并K个排序链表 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输 ...

  4. [leetcode 23]Merge k Sorted Lists

    1 题目 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexi ...

  5. [LeetCode] 23. Merge k Sorted Lists ☆☆☆☆☆

    转载:https://leetcode.windliang.cc/leetCode-23-Merge-k-Sorted-Lists.html 描述 Merge k sorted linked list ...

  6. 蜗牛慢慢爬 LeetCode 23. Merge k Sorted Lists [Difficulty: Hard]

    题目 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity ...

  7. LeetCode 23 Merge k Sorted Lists(合并k个有序链表)

    题目链接: https://leetcode.com/problems/merge-k-sorted-lists/?tab=Description Problem: 给出k个有序的list, 将其进行 ...

  8. [LeetCode]23. 合并K个排序链表(优先队列;分治待做)

    题目 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [   1->4->5,   1->3->4,   2->6 ] 输出: 1 ...

  9. Java [leetcode 23]Merge k Sorted Lists

    题目描述: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complex ...

  10. LeetCode(23)-Implement Queue using Stacks

    题目: Implement the following operations of a queue using stacks. push(x) -- Push element x to the bac ...

随机推荐

  1. 040 Combination Sum II 组合总和 II

    给定候选号码数组 (C) 和目标总和数 (T),找出 C 中候选号码总和为 T 的所有唯一组合.C 中的每个数字只能在组合中使用一次.注意:    所有数字(包括目标)都是正整数.    解决方案集不 ...

  2. 048 Rotate Image 旋转图像

    给定一个 n × n 的二维矩阵表示一个图像.将图像旋转 90 度(顺时针).注意:你必须在原矩阵中旋转图像,请不要使用另一个矩阵来旋转图像.例 1:给出的输入矩阵 = [  [1,2,3],  [4 ...

  3. asp.net mvc整合Nhibernate的配置方法

    http://blog.csdn.net/xz2001/article/details/8452794 http://www.cnblogs.com/GoodHelper/archive/2011/0 ...

  4. The great pleasure in life is doing what people say you cannot do.

    The great pleasure in life is doing what people say you cannot do.  人生最大的快乐是做到别人认为你做不到的事情.

  5. To run dex in process, the Gradle daemon needs a larger heap

    http://blog.csdn.net/u012995856/article/details/52595653

  6. Object-C反射读取实体属性和值

    举例: 首先定义TestModel如下: @interface TestModel : NSObject @property (nonatomic, strong) NSString *name; @ ...

  7. linux python升级及全局环境变量设置

    1.下载pythonwget https://www.python.org/ftp/python/3.4.5/Python-3.4.5.tgz 或者去官网下载压缩包 2.安装python3依赖yum ...

  8. UVA 536 TreeRocvery 树重建 (递归)

    根据先序历遍和中序历遍输出后序历遍,并不需要真的建树,直接递归解决 #include<cstdio> #include<cstring> ; char preOrder[N]; ...

  9. Windows 漏洞利用开发

    第一阶段:简单栈溢出 分析栈溢出原理 寻找溢出点,了解pattern_create和pattern_offset计算溢出点的原理 寻找JMP ESP跳板,分析利用JMP ESP跳板劫持程序流的原理 编 ...

  10. 二、antd pro 删除eslint检测

    删除package.json 里 " pre-commit": "npm run lint-staged" 这个对象就可以.