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. win7设置管理员权限

    1.在运行中输入:secpol.msc 2.修改设置权限设置 3.在账户中, 将administrator启用并设置密码 将其他用户取消管理原权限,设置为user权限

  2. python 8 函数

    调用函数 Python内置了很多有用的函数,我们可以直接调用. 要调用一个函数,需要知道函数的名称和参数,比如求绝对值的函数abs,只有一个参数.可以直接从Python的官方网站查看文档: 也可以在交 ...

  3. 第十五章 提升用户体验 之 设计实现MVC controllers 和 actions

    1. 概述 controllers 和 actions 是 ASP.NET MVC4中非常重要的组成部分. controller管理用户和程序间的交互,使用action作为完成任务的方式. 如果是包含 ...

  4. Git入门学习总结

    用了两天时间看完廖雪峰老师的git教程(http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b0 ...

  5. Python3+Selenium3+webdriver学习笔记5(模拟常用键盘和鼠标事件)

    #!/usr/bin/env python# -*- coding:utf-8 -*- from selenium import webdriverfrom selenium.webdriver.co ...

  6. Jenkins中启动从节点时,出现问题如何解决,问题:No Known Hosts...

    Jenkins中,启动从节点时,出现如下问题如何解决:/root/.ssh/known_hosts [SSH] No Known Hosts file was found at /root/.ssh/ ...

  7. robotframework介绍

    1.测试用例使用文本文件(TXT或者TSV文件)保存,使用制表符分隔数据.可以方便的使用任何文本编辑器,或者EXCEL编辑测试用例.也可以使用HTML格式创建用例.2.测试用例中支持变量使用,可以使用 ...

  8. jsp四大作用域之page

    <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding= ...

  9. python基础教程总结10——文件

    1.打开文件 open(name[mode[,buffing])    参数:  文件,模式,缓冲 1)name: 是强制选项,模式和缓冲是可选的 #如果文件不在,会报下面错误1 >>&g ...

  10. coredata 关系的删除规则

    http://blog.csdn.net/Hello_Hwc/article/details/46375517 关系的删除规则-Delete Rule Deny 关系的destination中只要有一 ...