算法训练营第二天

滑动窗口:

209.长度最小的子数组

开始没啥思路。只知道两个for O(n*2) 得到结果。看到题目要用滑动窗口,双指针。但根本对滑动窗口没有任何记忆。

滑动窗口:滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果

然后看了下 sliding window的定义在代码随想录上,然后再思考:

想到移动子序列对于这个题也就是 子数组。怎么更新子数组呢? start位置和end位置 要更新,这两个是指针,然后主数组就向右移动。有些思路:子数组终止位置时,子数组和大于target 就要尝试移动start位置。 这个移动是一个小的for,那时间复杂度是多少呢?有了这个想法就开始更新代码:

更新代码还是有问题,没搞对如何更新startPoint,以及子数组。先入僵局,测试没过。

那就完整的看下代码随想录:

(from 代码随想录)滑动窗口也可以理解为双指针法的一种!只不过这种解法更像是一个窗口的移动,所以叫做滑动窗口更适合一些。

在本题中实现滑动窗口,主要确定如下三点:

  • 窗口内是什么? 子数组
  • 如何移动窗口的起始位置?子数组的startPoint
  • 如何移动窗口的结束位置?子数组的endPoint

我没有做出来的原因,是移动startPoint 想法有问题

我的是比较混乱的 判断滑动条件以及滑动。

根本不需要这么麻烦:直接

总结:209

这道理思路思路没问题,就是实现startPoint这儿出现问题。逻辑没考虑好!时间复杂度:每一个点都会经历一次endPoint,每一个点最多会经历一次startPoint。所以O(n) = n. 循环的细节需要注意!!! 注意startPoint移动!!!!! 自己的逻辑差在startPoint没控制

59.螺旋矩阵II

好像23年面试实习时,有人问过,螺旋打印。

初想法是:

把每个点设置一个 if_hit 来判断是否赋值过,如果当遍历到赋值过的,赋值方向改变。遍历就4个方向,

up down left right.想法没问题 就是要加强把想法变成 代码的能力。在看claude前,自己控制方向的方法不对,对边界控制还是差。

按照我的思路看了claude后:

里面我没做到的 使用%4来控制下一次的方向。其次就是使用nextX,nextY来表示下一次移动到哪,然后判断需要换方向吗,如果需要的话,在处理真正的x y!

看答案后:

代码随想录里提出要坚持循环不变量原则。所以什么是循环不变量?需要好好理解!

代码随想录的解法是 一次loop 就完成一圈的填数字,然后下一圈就在大圈里 x,y各加1开始的点开始。需要注意这样最小圈是3*3的圈,里面还有有一点 需要额外处理! 这个思路也不错,在这里循环不变量原则 就是在每次loop 中,每一圈的up down left right需要用一致的处理方法。

区间和

这个题是***的题,算是代码随想录的原创题。不是leetcode上的题:*************************************************

是ACM模式,很好的锻炼!

初思路:

做这个题 首先我得承认自己忘了 std in 在java里如何实现,所以我用了claude 查了下:

  1. scanner:

可以使用hasNext()或hasNextLine(): 来检测是不是到了eof

然后 复习下 java里类型转化:比如 string -> int: Integer.parserInt();

自己的想法使用暴力解法,for a 到 b累加,这时间复杂度 超了。但超了后,自己想起来 求 2 - 5 可以用 sum(5) - sum(1) 得到。

这个题难点不是思路,而是 std in std out。也就是 ACM模式!后面需要多练习下 ACM模式!!!

看了代码随想录后:

还是没有写对,因为 累加这儿出错了,实现逻辑出现问题。并且并没有处理 边界问题! 需要认真!

这个代码出现了 很多小问题。要多回看! 比如 怎么std in std out 以及关于 类型转化。

开发商购买土地:

还是***里的题,对ACM模式练习有帮助

初想法:

这个题要求 横 或者 竖切,其实就是 (n-1)*(m-1) 种切法。在这里面找最小?在 std in 的过程中 可以很方便的 得到 一行的sum,横切的话 就是 行的sum 直接的对比,那如果是 竖切呢? 然后我又进一步思考 这个面积差,其实就是总面积 z , A得到 x, B得到y,A B的价差 最小,就是| 2y-z| 最小,也就是要找 最接近 z/2的面积。(这里的面积指的是 加上权后的)。然后也就是记录下每一行和每一列的sum。初想法实践后 还是错的,感觉代码写太少,很多条件逻辑 不熟,需要多做题。

看完代码随想录:

觉得自己的初想法是正确的,其实和 代码随想录的一样,只是我太关注在 用复杂的方式表示前缀和,其实就是上下,或者左右的node权重和。可以直接用for(m){for(n)}来处理。其实和我的意思是一样的。最后发现自己只是一个在给前m列的总node和处理时,判断条件应该是i < m,搞成了 i < n! 需要长教训。并且以后 可以 先从简单的方法来 就是代码随想录里提到的。代码随想录里把每一个node 先得到,然后再从 行切 开始,用for(m){for(n)}处理,然后到 行的最后一个数 就可以进行比较了,不用专门再用 for 比较。这是一个很好的代码习惯格式。

全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务