From 73993ff8c0fe79278c150147fe8c05f129bac2c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BB=93=E5=8F=91=E5=8F=97=E9=95=BF=E7=94=9F?= Date: Fri, 31 Aug 2018 22:10:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/_posts/算法/二进制有关问题两则.md | 3 +- source/_posts/算法/动态规划.md | 62 ++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 source/_posts/算法/动态规划.md diff --git a/source/_posts/算法/二进制有关问题两则.md b/source/_posts/算法/二进制有关问题两则.md index 683a22c..4da2c98 100644 --- a/source/_posts/算法/二进制有关问题两则.md +++ b/source/_posts/算法/二进制有关问题两则.md @@ -74,7 +74,8 @@ categories: 要求一个负数的补码 比如-2 那么要先对该数求绝对值, 就是2, 2对应的原码是 `0 0 0 0 0 0 1 0` -再+1就是`0 0 0 0 0 0 1 1`, 它就是-2的补码 +取反是`1 1 1 1 1 1 0 1` +再+1就是`1 1 1 1 1 1 1 0`, 它就是-2的补码 那么已知一个补码, 怎么求对应的十进制数呢? 首先看最高位判断正负, 如果是0, 那么它是个正数, 正数就是二进制转化十进制的基本规则 diff --git a/source/_posts/算法/动态规划.md b/source/_posts/算法/动态规划.md new file mode 100644 index 0000000..188244d --- /dev/null +++ b/source/_posts/算法/动态规划.md @@ -0,0 +1,62 @@ +--- +title: 动态规划 +date: 2018-8-27 02:17:07 +tags: + - 算法 + - 动态规划 +categories: + - 算法 +--- + +### 楔子 +最大子序和 ( leetcode题目 ) +给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 +> 示例: +输入: [-2,1,-3,4,-1,2,1,-5,4], +输出: 6 +解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 + + +题目只需要求最大的和是多少, 而不需要知道这个子数组的起止位置 +首先需要明确的是, 如果这个子数组的边缘位置(第一个或最后一个)元素是一个负数 +那么这个子数组的和肯定不是最大的, 因为舍掉这个元素, 之后的和肯定会更大, 负数是会让总和减小的 +比如[-3,4,-1,2] 这个子数组肯定不是最大, 因为把-3舍掉会更大 + +更进一步, 如果这个子数组边缘位置连续多个数的和是负数, 那么这多个数也可以舍掉, 让总和更大 +比如[1,-3,4,-1,2] 这个子数组肯定不是最大, 因为把1,-3舍掉, 可以让总和更大 + +以示例当中给出的数组进行推演 +[-2,1,-3,4,-1,2,1,-5,4] +( 下面的每个序号代表推进到第几个元素 ) +1. 总和初始值是0 , 先加第一个数此时总和是`-2` +2. 前面的总和-2, 加上它会使总和 **变小**, 所以不加, 总和 **归零**, 然后加1, 此时总和是`1` +3. 前面的总和1, 加上它会使总和 **变大**, 所以加上, 此时总和是`-2` +4. 前面的总和-2, 加上它会使总和 **变小**, 所以不加, 总和 **归零**, 然后加4, 此时总和是`4` +5. 前面的总和4, 加上它会使总和 **变大**, 所以加上, 此时总和是`3` + +..... +每一步是否舍弃前面总和的判断条件就是前面的总和是正还是负, 正数则加, 负数则舍弃 +依次进行下去, 从每一步得到的总和里面找出最大的就可以了 +每一步的总和分别是`-2 1 -2 4 3 5 6 1 5` +显然最大的是6 + +#### 代码实现 +```java +class Solution { + public int maxSubArray(int[] nums) { + if(nums.length == 0) { //特殊情况判断 + return 0; + } + int sum = nums[0], maxSum = nums[0]; + for(int i=1 ; i maxSum) { + maxSum = sum; + } + } + return maxSum; + } +} +``` +空间复杂度是`O(1)`, 因为使用了常数个变量, 没有开辟长度为n的新数组 +时间复杂度是`O(n)`, 因为要逐个遍历传入的数组当中的元素 \ No newline at end of file