首页 文章 精选 留言 我的

精选列表

搜索[url],共10006篇文章
优秀的个人博客,低调大师

ARTS 1101: 最长回文串与子序列匹配、一次 URL 请求的来回之旅与如何验证 AI 的交付

每周完成一个 ARTS: 至少做一个 leetcode 的算法题、阅读并点评至少一篇英文技术文章、学习至少一个技术技巧、分享一篇有观点和思考的技术文章。(也就是 Algorithm、Review、Tips、Share 简称 ARTS) ## Algorithm 这周也是两个 Easy 难度的题目,第一道题目:https://leetcode.cn/problems/longest-palindrome/description/?envType=study-plan-v2&envId=selected-coding-interview ![image-20261031143628349](https://developer.qcloudimg.com/http-save/10394799/4b8c164bdd2ca98ced3ed07eecdab4be.png) 这道题目关健就是看数量,看对应的字母出现了几次。比如,上面案例中的 abccccdd 这个内容,如果是类似于 c、d 这种有多个的一般都是可以组成对称的内容。但是还要注意一点,如果是有单独的字母,比如 a 、b 等等,我们也可以用到其中之一,用于构建回文串的。 思路: - 先拿到每一个 char 有多少个,这里使用 map 的 merge 方法 - 之后根据 char 对应的数量进行判断: + 如果是偶数的话那么可以自己在最终的 size 加上 + 如果是奇数的话,需要单独进行 - 1 操作(不可能是负数,以为 map 里面存的至少是 1 个),目的是为了凑偶数,这样后续方便计算 size + 但是奇数的情况下,还需要进行特殊处理,这里需要计算一下是否有单独一个字母的情况,如果有的话后续计算 size 的时候需要 + 1 ,但是不能每一个都进行 + 1,因为这个单独的一个字母最终是放到中间位置的,如果多个的话那么就无法对称了,也就不是回文字符串 ``` class Solution { public int longestPalindrome(String s) { HashMap strMap = new HashMap<>(); for (char c : s.toCharArray()) { strMap.merge(c, 1, Integer::sum); } int size = 0; boolean haveSingleChar = false; for (Map.Entry entry : strMap.entrySet()) { Integer value = entry.getValue(); if (value % 2 != 0) { haveSingleChar = true; value = value - 1; } if (value set = new HashSet<>(); int length = 0; for (char c : s.toCharArray()) { boolean ifPresent = set.add(c); if (!ifPresent) { set.remove(c); length = length + 2; } } return set.isEmpty() ? length : length + 1; } } ``` --- LeetCode https://leetcode.cn/problems/is-subsequence/description/?envType=study-plan-v2&envId=selected-coding-interview 题目: ![image-20261031220538733](https://developer.qcloudimg.com/http-save/10394799/1b26e1c7cea93decbc5f38011110a3e1.png) 这道题目是相对简单的双指针,也算是我第一道双指针的题目了(之前可能刷过但是忘记了),有一些注意事项: - 具体例子,还是具体例子,没有具体的例子我真的想不明白 - 外层循环开始的时候就是按照 index 从前向后,因为外层循环是要被匹配的字母,而内层的就是来源字符串。 - 外层循环 0 开始,但是内层循环却不可以,如果内存循环每一次都是从 0 开始的话,那么会导致误判, 比如 下面这个例子,aab. acb。并且开始的 index 也有讲究,必须是最后匹配到的 j 的顺序的下一位, 因为如果来源字符串中的一个字母已经被匹配到了,那么下一次循环的时候不能再判断当前的字母了 - 不只需要 index 还需要一个变量判断,这个变量的作用就是判断当前的内层循环,是否找到了对应的需要匹配的字母 如果一次循环没有找到的话,那么可以直接返回 false 了,因为循环完全的来源字符串都没有对应的字母,直接宣判 false 并且这个变量,每一次循环开始的时候需要设置成 false 否则,上一次外层循环判断的「垃圾」数据,就会干扰当前这次 循环的判断 ``` public boolean isSubsequence(String s, String t) { // 双指针解决 if (s.length() > t.length()) { return false; } int index = 0; boolean isFound = false; for (int i = 0; i 0 )); then printf '%dd %dh' "$days" "$hours" elif (( hours > 0 )); then printf '%dh %dm' "$hours" "$mins" else printf '%dm' "$mins" fi } # Gradient uses stable, full-width block characters: no fractional glyphs. context_bar() { local pct=$1 width=20 filled=0 i pos r g b offset if [[ $pct =~ ^[0-9]+$ ]]; then filled=$(((pct * width + 50) / 100)); fi for ((i = 0; i = filled )); then printf '%s░' "$TRACK" continue fi pos=$((i * 100 / (width - 1))) if ((pos <= 50)); then r=$(( 0 + 220 * pos / 50 )) g=200 b=$(( 80 - 80 * pos / 50 )) else offset=$((pos - 50)) r=220 g=$(( 200 - 160 * offset / 50 )) b=$(( 20 * offset / 50 )) fi printf '\033[38;2;%d;%d;%dm█' "$r" "$g" "$b" done printf '%s' "$RESET" } usage_color() { if [[ ! $1 =~ ^[0-9]+$ ]] || (( $1 < 70 )); then printf '%s' "$GREEN" elif (( $1 < 90 )); then printf '%s' "$YELLOW" else printf '%s' "$RED"; fi } NOW=$(date +%s) ctx_label=$(percent_text "$ctx") hit_label=$(percent_text "$hit") five_left=$(left_text "$used5") seven_left=$(left_text "$used7") five_reset=$(reset_after "$reset5") seven_reset=$(reset_after "$reset7") ctx_color=$(usage_color "$ctx") five_color=$(usage_color "$used5") seven_color=$(usage_color "$used7") printf '%s[%s · %s]%s ' "$MODEL_COLOR" "$model" "$effort" "$RESET" context_bar "$ctx" printf ' %s%s%s %s│%s %sHit%s %s%s\n' "$ctx_color" "$ctx_label" "$RESET" "$SEPARATOR" "$RESET" "$CYAN" "$RESET" "$CYAN" "$hit_label" printf '5h %s%s%s left %s·%s reset %s %s│%s 7d %s%s%s left %s·%s reset %s\n' \ "$five_color" "$five_left" "$RESET" "$DIM" "$RESET" "$five_reset" "$SEPARATOR" "$RESET" \ "$seven_color" "$seven_left" "$RESET" "$DIM" "$RESET" "$seven_reset" ``` ## Share 文章:[More than just code review](https://simonwillison.net/2026/Aug/22/more-than-just-code-review/) 这周看到 Simon Willison 分享了一个关于 AI Coding 的观点。Simon 是 Django 的共同创建者之一,也一直在实践和分享 AI 编程。他认为,想要有效使用 Coding Agent,需要能够清楚地告诉它要做什么,并且有把握地验证修改是否正确。 1、能描述需求,也需要知道怎么判断结果。 以前自己写代码时,需要考虑怎么实现;使用 Agent 后,我们可以先描述需求,让它去寻找和修改代码。但是,描述得越清楚,后面越容易判断它有没有完成任务。比如,不只是说「做一个双指针动画」,还可以说明两个指针分别代表什么、什么时候移动,以及匹配成功或失败时应该显示什么。 Agent 把功能做出来之后,还需要回到需求本身,确认结果是否符合预期。如果一开始自己也不知道正确结果是什么,就很难判断它交付的东西是否可靠。 2、验证不只有逐行阅读代码。 Simon 提到,逐行检查代码有时是必要的,但验证修改还有其他方法。比如运行程序、查看实际效果、准备测试数据,以及针对容易出错的情况做测试。这些方法可以和代码审查结合使用,具体选择取决于改动的内容和风险。 以这周的子序列动画为例,除了看页面能否打开,还可以输入 `aab` 和 `acb`,观察同一个字符会不会被重复匹配;再试试空字符串、完全匹配和不匹配的情况,看看指针移动和最终结果是否符合预期。这样验证的是实际行为,而不只是代码看起来有没有问题。 3、使用 AI 之后,对问题的理解仍然很重要。 这次做动画演示,也是希望通过具体例子帮助自己理解双指针。如果不清楚题目要求和指针应该怎样移动,即使 AI 很快生成了一个页面,也不容易发现演示里的错误。 我觉得 AI 确实让我们可以更快地尝试想法,但做出来只是第一步。之后还要根据用途决定怎么检查:个人学习工具可以先用几个例子验证,涉及真实用户和重要数据的功能,则需要更充分的测试和审查。理解问题、提出要求和验证结果,依然是使用 AI 时需要自己关注的事情。

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册