ARTS挑战打卡第二十周

Algorithm-一周至少一道算法题

Review-阅读并点评至少一篇英文技术文章

Tip-学习至少一个技术技巧,总结和归纳在日常工作中所遇到的知识点

Share-分享一篇有观点和思考的技术文章

01-Algorthm

   ———————  

1、树

https://leetcode.com/problems/path-sum-ii

https://leetcode.com/problems/binary-tree-paths/

两题类型很像,找从根节点到叶子节点的路径中,符合条件的路径。

解法:增加一个表缓存上一步计算的结果,接下来就是递归。

2、动态规划

https://leetcode.com/problems/longest-increasing-subsequence

最长递增子序列

用动态规划解答这题,定义dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列的长度。

比如序列,nums:143423,下标从0开始,那么得到的dp数组就是122333

根据题目描述,最终是要把dp[0~5]计算出来,然后返回dp中的最大值。所以题目的核心是,如果知道了dp[0],如何求dp[1],如果知道了dp[0~4],怎么求dp[5]。

dp数组默认初始化都为1,在求dp[1]时,只要判断nums[1]与nums[0],如果nums[1] > nums[0],dp[1]=dp[0]+1=2;否则dp[1]=1。

以此类推,求dp[5]时,把nums[5]与nums[4]比较,如果nums[5] > nums[4],dp值就加一。

for (int j = 0; j < i; j++) {
  if (nums[i] > nums[j])
    dp[i] = Math.max(dp[i], dp[j] + 1);
}

这种思路类似于数学归纳法的证明,假设结论在 k`<`n 时成立,然后想办法证明 k=n 的时候此结论也成立。如果能够证明出来,那么就说明这个结论对于 k 等于任何数都成立。

https://leetcode.com/problems/increasing-triplet-subsequence

这一题要判断序列中是否有包含至少3个元素的递增序列。

解法一:可以用动态规划,只要dp数组存在值为3的元素,就说明存在递增。(O(n2),提交运行时长是 56ms)

解法二:创建两个辅助变量,记录每个值前面比它小的数字,只要前面有两个比它小的数字,说明存在3个元素的递增序列。(只需要一次循环,运行时长是O(n),提交运行时长是 0ms)

02-Review

——————

1、https://www.nginx.com/blog/event-driven-data-management-microservices/

微服务架构中,为了良好的封装性和数据的隔离性,每个服务都会有独立的数据库,那么带来的问题是如何保证数据的一致性和在一个接口中,通过多个微服务组装数据。

大部分会用消息队列来同步数据,提供的是最终一致性,通过事件驱动模型来通知数据的更新,这样就能及时获得数据的更新通知。

2、https://www.nginx.com/blog/deploying-microservices/

如何部署微服务?

可以使用虚拟机、容器(k8s)、Aws Lambda等等技术,目前比较常见的还是虚拟机的方式,而大部分公司都逐渐改为k8s部署的方案,容器化的时代早已到来。

3、https://www.nginx.com/blog/refactoring-a-monolith-into-microservices/

介绍了如何重构一个单体服务为微服务架构。

最重要的是,不要计划一次性去改动,应该逐步重构

重构过程中,旧项目不应该再新增代码,新的代码应写到重构完成的代码中

如何处理原旧有单体服务的数据,三个方案:

  • 在原来单体服务里面单独提供一个API来查询和写入

  • 直接连接旧的数据库

  • 维护两套数据,双写

前后端分离

微服务提取

从简单明了的开始,抽象出领域模型,提取为一个模块,然后部署到单独的服务

03-Tip

——————

1、在Java8中,分组后取分组列表中按照某种排序规则得到最大的值

Map<String, Config> configMap = configList.parallelStream().collect(
              Collectors.groupingBy(Config::getId, // 先根据Id分组
               Collectors.collectingAndThen(
               Collectors.reducing((c1,  c2) -> c1.getVersion() > c2.getVersion() ? c1 : c2), Optional::get)));

2、动态规划题目的解法流程:

首先明确 dp 数组所存数据的含义。这步很重要,如果不得当或者不够清晰,会阻碍之后的步骤。

根据 dp 数组的定义,运用数学归纳法的思想,假设 dp[0...i-1] 都已知,想办法求出 dp[i],一旦这一步完成,整个题目基本就解决了。

但如果无法完成这一步,很可能就是dp数组的定义不够恰当,需要重新定义 dp 数组的含义;或者可能是 dp 数组存储的信息还不够,不足以推出下一步的答案,需要把 dp 数组扩大成二维数组甚至三维数组。

最后想一想问题的 base case 是什么,以此来初始化 dp 数组,以保证算法正确运行。

计算机解决问题其实没有任何奇技淫巧,它唯一的解决办法就是穷举,穷举所有可能性。算法设计无非就是先思考“如何穷举”,然后再追求“如何聪明地穷举”。比如加备忘录、DP table,用空间换时间。

04-Share

—————

分享关于写作的两篇文章:

坚持新媒体写作第21天了,聊聊我为什么喜欢写作

认真分享如何开始写作的5条建议

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值