leetcode-23-DynamicProgramming-1
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的更多相关文章
- [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 ...
- LeetCode 23. 合并K个排序链表(Merge Two Sorted Lists)
23. 合并K个排序链表 23. Merge k Sorted Lists 题目描述 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. LeetCode23. Merge k S ...
- Java实现 LeetCode 23 合并K个排序链表
23. 合并K个排序链表 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输 ...
- [leetcode 23]Merge k Sorted Lists
1 题目 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexi ...
- [LeetCode] 23. Merge k Sorted Lists ☆☆☆☆☆
转载:https://leetcode.windliang.cc/leetCode-23-Merge-k-Sorted-Lists.html 描述 Merge k sorted linked list ...
- 蜗牛慢慢爬 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 ...
- LeetCode 23 Merge k Sorted Lists(合并k个有序链表)
题目链接: https://leetcode.com/problems/merge-k-sorted-lists/?tab=Description Problem: 给出k个有序的list, 将其进行 ...
- [LeetCode]23. 合并K个排序链表(优先队列;分治待做)
题目 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1 ...
- Java [leetcode 23]Merge k Sorted Lists
题目描述: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complex ...
- LeetCode(23)-Implement Queue using Stacks
题目: Implement the following operations of a queue using stacks. push(x) -- Push element x to the bac ...
随机推荐
- win7设置管理员权限
1.在运行中输入:secpol.msc 2.修改设置权限设置 3.在账户中, 将administrator启用并设置密码 将其他用户取消管理原权限,设置为user权限
- python 8 函数
调用函数 Python内置了很多有用的函数,我们可以直接调用. 要调用一个函数,需要知道函数的名称和参数,比如求绝对值的函数abs,只有一个参数.可以直接从Python的官方网站查看文档: 也可以在交 ...
- 第十五章 提升用户体验 之 设计实现MVC controllers 和 actions
1. 概述 controllers 和 actions 是 ASP.NET MVC4中非常重要的组成部分. controller管理用户和程序间的交互,使用action作为完成任务的方式. 如果是包含 ...
- Git入门学习总结
用了两天时间看完廖雪峰老师的git教程(http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b0 ...
- Python3+Selenium3+webdriver学习笔记5(模拟常用键盘和鼠标事件)
#!/usr/bin/env python# -*- coding:utf-8 -*- from selenium import webdriverfrom selenium.webdriver.co ...
- Jenkins中启动从节点时,出现问题如何解决,问题:No Known Hosts...
Jenkins中,启动从节点时,出现如下问题如何解决:/root/.ssh/known_hosts [SSH] No Known Hosts file was found at /root/.ssh/ ...
- robotframework介绍
1.测试用例使用文本文件(TXT或者TSV文件)保存,使用制表符分隔数据.可以方便的使用任何文本编辑器,或者EXCEL编辑测试用例.也可以使用HTML格式创建用例.2.测试用例中支持变量使用,可以使用 ...
- jsp四大作用域之page
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding= ...
- python基础教程总结10——文件
1.打开文件 open(name[mode[,buffing]) 参数: 文件,模式,缓冲 1)name: 是强制选项,模式和缓冲是可选的 #如果文件不在,会报下面错误1 >>&g ...
- coredata 关系的删除规则
http://blog.csdn.net/Hello_Hwc/article/details/46375517 关系的删除规则-Delete Rule Deny 关系的destination中只要有一 ...