LeetCode每日一题环形子数组的最大和 (中等)

调查动态规划,要点关注动态规划思想和代码完成。

       total += nums[i]
        currMax = max(currMax+nums[i], nums[i])
        maxSum  = max(maxSum, currMax)

标题描绘:

给定一个长度为 n 的环形整数数组 nums ,回来 nums 的非空 子数组 的最大可能和 。

环形数组 意味着数组的结尾将会与最初相连呈环状。形式上, nums[i] 的下一个元素是 nums[(i + 1) % n] , nums[i] 的前一个元素是 nums[(i – 1 + n) % n] 。

子数组 最多只能包括固定缓冲区 nums 中的每个元素一次。形式上,关于子数组 nums[i], nums[i + 1], …, nums[j] ,不存在 i <= k1, k2 <= j 其间 k1 % n == k2 % n 。

示例

  • 示例 1:

输入:nums = [1,-2,3,-2] 输出:3 解说:从子数组 [3] 得到最大和 3

  • 示例 2:

输入:nums = [5,-3,5] 输出:10 解说:从子数组 [5,5] 得到最大和 5 + 5 = 10

  • 示例 3:

输入:nums = [3,-2,2,-3] 输出:3 解说:从子数组 [3] 和 [3,-2,2] 都能够得到最大和 3

解题思路

最开端的时分,思路:遍历num数组,获取最大的数,从此数开端。然后向左右俩边辐射,若是正数,直接相加。若是负数,则持续向左右俩边遍历。 然后代码写如下

func maxSubarraySumCircular(nums []int) int {
    max := 0
    index := 0
    leng := len(nums)
    for i:=0 ; i < leng ; i++{
        if max < nums[i]{
            max = nums[i]
            index := i
        }
    }//找最大值,以及其所对应得下标
    if nums[(index+1)%n] >0 {
        max = max+ nums[(index+1)%n]
    }
    if nums[(index-1)%n] >0 {
        max = max+ nums[(index-1)%n]
    }//左右俩边大于0 ,就将其加入max中
    //假如小于0,也不能直接舍弃,还要判别该负数的下一个是不是正数且大于该负数的绝对值。
    //有个问题,如是不是应该悉数用循环来遍历整个数组。
    //不能这么做了,由于你不知道究竟是不是满足大于0,。
    //要不运用昨天的方法,
    if nums[(index+1)%n] <=0 {
        for k := 0 ; k < leng -1 ;k++{
            k = (k+ index +1)%n//这个是负数的下标
        }
    }
}

很明显,由于你不确定究竟后续还能不能取得一个大于0的数,所以这种方法肯定不能够。

然后换一种方法,能不能像昨天的标题一样,将数组中的每个数都差一个下标。然后进行排序。

假如这样做,思路便是:先将其从大到小排序?(坏,如同不一定从大的数开端便是正确的 ,比方 -7 7 -8 -9 1 2 -7这样,明显不能把-7包进去)

所以说,唔,仍是先按从大到小排。然后读榜首个数的时分,将其左右两边的数同加直到碰到下一个正数,

官方回答 (动态规划)

这题一共有两种状况 下面的这个子数组指最大和的子数组

榜首种状况:这个子数组不是环状的,便是说首尾不相连。

第二种状况:这个子数组一部分在首部,一部分在尾部,咱们能够将这第二种状况转换成榜首种状况

如下图:

7.20 每日学习(动态规划,双指针,正反向代理)

所以这最大的环形子数组和 = max(最大子数组和,数组总和-最小子数组和)

证明

证明一下第二种状况(最大子数组是环形的)

max(前缀数组+后缀数组)

= max(数组总和 – subarray) subarray指的是前缀数组和后缀数组中心的数组

= 数组总和 + max(-subarray) 数组总和是不变的,直接提出来

= 数组总和 – min(subarry) 。。。这个都懂吧,把负号提出来,max变成min

极端状况:假如说这数组的所稀有都是负数,那么上面的公式还需求变一下,由于这种状况,关于上面的榜首种状况sum会等于数组中的最大值,而对二种状况sum=0(最小的子数组便是本数组,total-total=0)。所以多加一个case,判别最大子数组和是否小于0,小于0,直接回来该maxSubArray

代码如下:

func maxSubarraySumCircular(nums []int) int {
    total, maxSum, minSum, currMax, currMin := nums[0], nums[0], nums[0], nums[0], nums[0]
    for i := 1; i < len(nums); i++ {
        total += nums[i]
        currMax = max(currMax+nums[i], nums[i])
        maxSum  = max(maxSum, currMax)
        currMin = min(currMin+nums[i], nums[i])
        minSum  = min(minSum, currMin)
    }
    //等价于if maxSum < 0
    if total == minSum  {
        return maxSum
    } else {
        return max(maxSum, total - minSum)
    }
}
func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}
func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}
作者:xing-you-ji
链接:https://leetcode.cn/problems/maximum-sum-circular-subarray/solution/wo-hua-yi-bian-jiu-kan-dong-de-ti-jie-ni-892u/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者取得授权,非商业转载请注明出处。

代码解说

    for i := 1; i < len(nums); i++ {
        total += nums[i]
        currMax = max(currMax+nums[i], nums[i])
        maxSum  = max(maxSum, currMax)
        currMin = min(currMin+nums[i], nums[i])
        minSum  = min(minSum, currMin)
    }

这段代码是运用Go语言编写的用于查找一个整数数组nums中的最大子数组和和最小子数组和的算法。代码运用了动态规划的思想来逐渐更新当时的最大子数组和maxSum、当时的最小子数组和minSum、当时最大子数组和的累加值currMax和当时最小子数组和的累加值currMin。

(这一块代码是核心,动态规划来更新大小,假如我写的话,应该不会关注min的取值,只会写前三行,也便是我考虑的第二种状况是把他当成榜首种状况相同,前面证明的变形太细了!)

if total == minSum

这是一个条件判别句子,用于查看数组的总和total是否等于最小子数组和minSum。 假如数组的总和等于最小子数组和,那么这意味着数组中的所有元素都是非正数(负数或零), 由于minSum是最小子数组和,而total是整个数组的总和。在这种状况下,数组中没有正数,由于假如有正数,将其加入到子数组和中,将会使得子数组和变得更大,而这与minSum持平是矛盾的。

LeetCode面试经典150题第4题:删去有序数组中的重复项 II(中等)

标题描绘:

给你一个有序数组 nums ,请你 原地 删去重复呈现的元素,使得呈现次数超越两次的元素只呈现两次 ,回来删去后数组的新长度。

不要运用额定的数组空间,你必须在 原地 修改输入数组 并在运用 O(1) 额定空间的条件下完成。

示例

  • 示例 1:

输入:nums = [1,1,1,2,2,3] 输出:5, nums = [1,1,2,2,3] 解说:函数应回来新长度 length = 5, 而且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。 不需求考虑数组中超出新长度后面的元素。

  • 示例 2:

输入:nums = [0,0,1,1,1,1,2,3,3] 输出:7, nums = [0,0,1,1,2,3,3] 解说:函数应回来新长度 length = 7, 而且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。 不需求考虑数组中超出新长度后面的元素

解题思路

由于此题数组内已经按大小排序了,所以只需求建立一个检测量signal,然后去判别重复数是否超越2个即可。 仅有需求留意的点是,不能新建一个数组去存储,而是要在原有的数组上进行操作!

没有啥需求留意的,感觉像简单难度。 代码如下:

//此题数组内已经按大小排序了,所以只需求建立一个检测量signal=2,然后去判别重复数是否超越2个
func removeDuplicates(nums []int) int {
    leng := len(nums)
    signal := 1 
    j :=2 
    for i:=2 ; i< len(nums) ; i++{
        if nums[i] == nums[j-1] && nums[i]==nums[j-2]{
            signal =0
        }
        if signal ==0{
            leng--
        }else{
            nums[j]= nums[i]
            j++
        }
        signal = 1
    }
    return leng
}

我的解法,其实运用于较小位,假如保存k位,且k很大,我肯定不能罗列完。

官方回答(双指针)

通用解法

为了让解法更具有一般性,咱们将原问题的「保存 2 位」修改为「保存 k 位」。

由于给定数组是有序的,所以相同元素必定接连。咱们能够运用双指针处理本题,遍历数组查看每一个元素是否应该被保存,假如应该被保存,就将其移动到指定方位。

详细地,咱们界说两个指针 slow 和 fast 分别为慢指针和快指针,其间慢指针表示处理出的数组的长度快指针表示已经查看过的数组的长度,即 nums[fast] 表示待查看的榜首个元素,nums[slow−1] 为上一个应该被保存的元素所移动到的指定方位。

由于本题要求相同元素最多呈现两次而非一次,所以咱们需求查看上上个应该被保存的元素 nums[slow−2] 是否和当时待查看元素 nums[fast] 相同。当且仅当 nums[slow−2]=nums[fast] 时,当时待查看元素nums[fast] 不该该被保存(由于此时必定有 nums[slow−2]=nums[slow−1]=nums[fast])。最终,slow即为处理好的数组的长度。

特别地,数组的前两个数必定能够被保存,因此关于长度不超越 2 的数组,咱们无需进行任何处理,关于长度超越 2的数组,咱们直接将双指针的初始值设为 2 即可。

假如是保存k位nums[slow-2] != nums[fast]将2改为k即可。一起初值也跟着改。

func removeDuplicates(nums []int) int {
    n := len(nums)
    if n <= 2 {
        return n
    }
    slow, fast := 2, 2
    for fast < n {
        if nums[slow-2] != nums[fast] {
            nums[slow] = nums[fast]
            slow++
        }
        fast++
    }
    return slow
}
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-array-ii/solution/shan-chu-pai-xu-shu-zu-zhong-de-zhong-fu-yec2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者取得授权,非商业转载请注明出处。

唔,仍是写复杂了很多,悲

正反向代理

docker建立haproxy 四层代理,一起3个后端web服务器,露出8000端口,做负载均衡,后端服务器采用RR的方式,恣意一个Sever挂掉,不影响8000端口宿主机的访问

1.创建一个 Docker Compose 文件来界说 HAProxy 和三个后端 Web 服务器容器。咱们将运用 Docker Hub 中的 haproxy 映像和 nginx 等简单 Web 服务器的三个实例来进行演示。docker-compose文件如下

services:
haproxy:  
image:haproxy:latest  
ports:  
-"8000:8000"  
volumes:  
-./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg  
networks:  
-proxy_network  
backend1:  
image:python:3  
command:python-mhttp.server80  
networks:  
-proxy_network  
backend2:  
image:python:3  
command:python-mhttp.server80  
networks:  
-proxy_network  
backend3:  
image:python:3  
command:python-mhttp.server80  
networks:  
-proxy_network  
networks:  
proxy_network:

2.haproxy.cfg如下

daemon
maxconn256  
defaults  
modetcp  
timeoutconnect5000ms  
timeoutclient50000ms  
timeoutserver50000ms  
frontendhttp-in  
bind*:8000  
default_backendbackend_servers  
backendbackend_servers  
modetcp  
balanceroundrobin  
serverbackend1backend1:80check  
serverbackend2backend2:80check  
serverbackend3backend3:80check