<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Python on 一共十七划</title>
		<link>https://noirzh.com/categories/python/</link>
		<description>Recent content in Python on 一共十七划</description>
		<generator>Hugo</generator>
		<language>zh-CN</language>
		
		
		
		
			<lastBuildDate>Sat, 17 Feb 2024 16:11:25 +0800</lastBuildDate>
		
			<atom:link href="https://noirzh.com/categories/python/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>题解-需要添加的硬币的最小数量-最大化在缺口处补硬币的作用</title>
				<link>https://noirzh.com/%E9%A2%98%E8%A7%A3-%E9%9C%80%E8%A6%81%E6%B7%BB%E5%8A%A0%E7%9A%84%E7%A1%AC%E5%B8%81%E7%9A%84%E6%9C%80%E5%B0%8F%E6%95%B0%E9%87%8F-%E6%9C%80%E5%A4%A7%E5%8C%96%E5%9C%A8%E7%BC%BA%E5%8F%A3%E5%A4%84%E8%A1%A5/</link>
				<pubDate>Sun, 03 Dec 2023 12:05:00 +0800</pubDate>
				<guid>https://noirzh.com/%E9%A2%98%E8%A7%A3-%E9%9C%80%E8%A6%81%E6%B7%BB%E5%8A%A0%E7%9A%84%E7%A1%AC%E5%B8%81%E7%9A%84%E6%9C%80%E5%B0%8F%E6%95%B0%E9%87%8F-%E6%9C%80%E5%A4%A7%E5%8C%96%E5%9C%A8%E7%BC%BA%E5%8F%A3%E5%A4%84%E8%A1%A5/</guid>
				<description>&lt;blockquote&gt;&#xD;&#xA;&lt;p&gt;Problem: &lt;a href=&#34;https://leetcode.cn/problems/minimum-number-of-coins-to-be-added/description/&#34;&gt;100153. 需要添加的硬币的最小数量&lt;/a&gt;&lt;/p&gt;&#xD;&#xA;&lt;/blockquote&gt;&#xD;&#xA;&lt;h2&gt;思路&lt;/h2&gt;&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;这题和&lt;a href=&#34;https://leetcode.cn/problems/maximum-number-of-consecutive-values-you-can-make/description/&#34;&gt;LeetCode-1798. 你能构造出连续值的最大数目&lt;/a&gt;很像,很经典的想法&lt;/li&gt;&#xD;&#xA;&lt;li&gt;是子序列所以先排序&lt;/li&gt;&#xD;&#xA;&lt;li&gt;先考虑我们手里的硬币能构造出来多少&lt;/li&gt;&#xD;&#xA;&lt;li&gt;假设我们手里的硬币足够我们构造出来[0,x),接下来我们又拿到了一个硬币,数值为y,&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;如果我们把y放进之前的所有序列之中,会发现我们能够构造[y,x+y)&lt;/li&gt;&#xD;&#xA;&lt;li&gt;再加上刚才的区间,我们手里的硬币加y之后能构造的数的范围为$[0,x)\bigcup[y,x+y)$&lt;/li&gt;&#xD;&#xA;&lt;li&gt;如果y&amp;lt;=x则我们能够构造的数就能达到[0,x+y)&lt;/li&gt;&#xD;&#xA;&lt;li&gt;如果y&amp;gt;x则会有一段空缺&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;/li&gt;&#xD;&#xA;&lt;li&gt;为了填补这段空缺,我们应该往里面放另一块硬币,假设为z,根据上面的推论,我们很容易得到z会生成的片段为[z,x+z),而且z的取值范围应该为[y-x,x],为了让填补有效,且最大化填补的内容,应该让z=x,因为这样能最大化填补的空缺&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;取最大更有可能单次填补完空缺&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;/li&gt;&#xD;&#xA;&lt;li&gt;而我们遇到的问题只是将y换成了target,所有遇到的大于当前x的也认为是y即可&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;h2&gt;Code&lt;/h2&gt;&#xD;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-python&#34;&gt;class Solution:&#xD;&#xA;    def minimumAddedCoins(self, coins: List[int], target: int) -&amp;gt; int:&#xD;&#xA;        coins.sort()&#xD;&#xA;        res=0&#xD;&#xA;        canMake=0 #能生成的范围是[0,canMake]&#xD;&#xA;        i=0&#xD;&#xA;        while i&amp;lt;(len(coins)):&#xD;&#xA;            val=coins[i]&#xD;&#xA;            if val&amp;lt;=canMake+1:&#xD;&#xA;                canMake+=val&#xD;&#xA;                i+=1&#xD;&#xA;            else:&#xD;&#xA;                res+=1 #这里补的硬币就是canMake+1&#xD;&#xA;                canMake+=canMake+1&#xD;&#xA;        while canMake&amp;lt;target:&#xD;&#xA;            res+=1&#xD;&#xA;            canMake+=canMake+1&#xD;&#xA;        return res&lt;/code&gt;&lt;/pre&gt;&#xD;&#xA;&lt;p&gt;&lt;audio controls=&#34;True&#34; preload=&#34;none&#34;&gt;&lt;source src=&#34;https://noirzh.com/wp-content/uploads/2023/12/03.光降るなあ.flac&#34; type=&#34;audio/flac&#34;/&gt;&lt;/audio&gt;&lt;/p&gt;</description>
			</item>
			<item>
				<title>题解-统计子串中的唯一字符-哈希表&#43;栈，计算贡献</title>
				<link>https://noirzh.com/%E9%A2%98%E8%A7%A3-%E7%BB%9F%E8%AE%A1%E5%AD%90%E4%B8%B2%E4%B8%AD%E7%9A%84%E5%94%AF%E4%B8%80%E5%AD%97%E7%AC%A6-%E5%93%88%E5%B8%8C%E8%A1%A8%E6%A0%88%EF%BC%8C%E8%AE%A1%E7%AE%97%E8%B4%A1%E7%8C%AE/</link>
				<pubDate>Sun, 26 Nov 2023 16:17:28 +0800</pubDate>
				<guid>https://noirzh.com/%E9%A2%98%E8%A7%A3-%E7%BB%9F%E8%AE%A1%E5%AD%90%E4%B8%B2%E4%B8%AD%E7%9A%84%E5%94%AF%E4%B8%80%E5%AD%97%E7%AC%A6-%E5%93%88%E5%B8%8C%E8%A1%A8%E6%A0%88%EF%BC%8C%E8%AE%A1%E7%AE%97%E8%B4%A1%E7%8C%AE/</guid>
				<description>&lt;blockquote&gt;&#xD;&#xA;&lt;p&gt;Problem: &lt;a href=&#34;https://leetcode.cn/problems/count-unique-characters-of-all-substrings-of-a-given-string/description/&#34;&gt;828. 统计子串中的唯一字符&lt;/a&gt;&lt;/p&gt;&#xD;&#xA;&lt;/blockquote&gt;&#xD;&#xA;&lt;h2&gt;思路&lt;/h2&gt;&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;注意到一个唯一字符对数个子串生效，也就是在多个子串中唯一字符是固定的那几个，很容易想到贡献法&lt;/li&gt;&#xD;&#xA;&lt;li&gt;对于子串起点和终点我们设置成$left,right$,任意字符位置为$a_i$序列,让子串生效的范围是$left-right$这个范围内,存在一个字符a,其序列满足&lt;br/&gt;$$a_{i-1}&amp;lt;left&amp;lt;=a_i&amp;lt;=right&amp;lt;a_{i+1}$$,&lt;/li&gt;&#xD;&#xA;&lt;li&gt;同样可以通过枚举起点终点,得知满足这个条件子串的个数为 $(a_i-a_{i-1})*(a_{i+1}-a_{i})$,&lt;/li&gt;&#xD;&#xA;&lt;li&gt;为了计算方便我们将-1和n作为每个字符的两端,既$a_{-1}=-1,a_{n+1}=n$&lt;/li&gt;&#xD;&#xA;&lt;li&gt;该字母在$a_i$上为答案做的贡献就等于子串的数量&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;h2&gt;解题方法&lt;/h2&gt;&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;使用哈希表存储每个字母的位置序列&lt;/li&gt;&#xD;&#xA;&lt;li&gt;为了前后方便我们使用栈来维护具体的字母序列&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;blockquote&gt;&#xD;&#xA;&lt;p&gt;时间复杂度,O(n)&lt;br/&gt;空间复杂度,O(n)&lt;/p&gt;&#xD;&#xA;&lt;/blockquote&gt;&#xD;&#xA;&lt;h2&gt;Code&lt;/h2&gt;&#xD;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-python&#34;&gt;class Solution:&#xD;&#xA;    def uniqueLetterString(self, s: str) -&amp;gt; int:&#xD;&#xA;        n=len(s) &#xD;&#xA;        hash=[[n] for _ in range(26)] #最右端点&#xD;&#xA;        for i in range(len(s)-1,-1,-1):&#xD;&#xA;            hash[ord(s[i])-ord(&#39;A&#39;)].append(i)&#xD;&#xA;            #小的在顶部,大的在底部&#xD;&#xA;        res=0&#xD;&#xA;        for i in range(26):&#xD;&#xA;            pre=-1&#xD;&#xA;            while len(hash[i])&amp;gt;1:&#xD;&#xA;                index=hash[i].pop()&#xD;&#xA;                back=hash[i][-1]&#xD;&#xA;                res+=(index-pre)*(back-index)&#xD;&#xA;                pre=index&#xD;&#xA;        return res&lt;/code&gt;&lt;/pre&gt;</description>
			</item>
			<item>
				<title>题解-找到 Alice 和 Bob 可以相遇的建筑-单调栈&#43;二分&#43;离线</title>
				<link>https://noirzh.com/%E9%A2%98%E8%A7%A3-%E6%89%BE%E5%88%B0-alice-%E5%92%8C-bob-%E5%8F%AF%E4%BB%A5%E7%9B%B8%E9%81%87%E7%9A%84%E5%BB%BA%E7%AD%91-%E5%8D%95%E8%B0%83%E6%A0%88%E4%BA%8C%E5%88%86%E7%A6%BB%E7%BA%BF/</link>
				<pubDate>Sun, 19 Nov 2023 14:19:00 +0800</pubDate>
				<guid>https://noirzh.com/%E9%A2%98%E8%A7%A3-%E6%89%BE%E5%88%B0-alice-%E5%92%8C-bob-%E5%8F%AF%E4%BB%A5%E7%9B%B8%E9%81%87%E7%9A%84%E5%BB%BA%E7%AD%91-%E5%8D%95%E8%B0%83%E6%A0%88%E4%BA%8C%E5%88%86%E7%A6%BB%E7%BA%BF/</guid>
				<description>&lt;blockquote&gt;&#xD;&#xA;&lt;p&gt;Problem: &lt;a href=&#34;https://leetcode.cn/problems/find-building-where-alice-and-bob-can-meet/description/&#34;&gt;100110. 找到 Alice 和 Bob 可以相遇的建筑&lt;/a&gt;&lt;/p&gt;&#xD;&#xA;&lt;/blockquote&gt;&#xD;&#xA;&lt;h2&gt;思路&lt;/h2&gt;&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;分解一下题目,发现和Alice和Bob二人顺序没关系,为了方便,我们假设Alice所在建筑位置在左边,称为a,bob就会在右边,称为b&lt;/li&gt;&#xD;&#xA;&lt;li&gt;假设a,b相等,则所在的位置就是b&lt;/li&gt;&#xD;&#xA;&lt;li&gt;若b所在高度大于a,则答案是b&lt;/li&gt;&#xD;&#xA;&lt;li&gt;剩下的就是我们要考虑的一般情况:b的高度小于a,&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;h2&gt;解题方法&lt;/h2&gt;&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;我们要做的明确,查b的右侧大于a的第一个建筑&lt;/li&gt;&#xD;&#xA;&lt;li&gt;每次都向后查询显然时间复杂度不够,遍历q又是必须的,所以我们想把这个查询压到log级别&lt;/li&gt;&#xD;&#xA;&lt;li&gt;显然可以通过维护右侧单调栈+二分的模式&lt;/li&gt;&#xD;&#xA;&lt;li&gt;但是为每一个点都配单调栈内存不够&lt;/li&gt;&#xD;&#xA;&lt;li&gt;我们发现左边的单调栈一定是右边的转过来的&lt;/li&gt;&#xD;&#xA;&lt;li&gt;所以我们只需要维护一个单调栈&lt;/li&gt;&#xD;&#xA;&lt;li&gt;在遇到对于要处理的点的查询的时候直接查询就行&lt;/li&gt;&#xD;&#xA;&lt;li&gt;也就是我们总体过程是离线查询+单调栈+二分&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;h2&gt;代码细节&lt;/h2&gt;&#xD;&#xA;&lt;ol&gt;&#xD;&#xA;&lt;li&gt;我们先用哈希表记录查询,保证不漏:&lt;/li&gt;&#xD;&#xA;&lt;li&gt;先保证a&amp;lt;=b&lt;/li&gt;&#xD;&#xA;&lt;li&gt;以b为key,存储想查询的值:a和答案位置i&lt;/li&gt;&#xD;&#xA;&lt;li&gt;需要注意的是可能存在多个a的情况,需要用列表而不是一一对应&lt;/li&gt;&#xD;&#xA;&lt;li&gt;从后向前遍历,维护单调栈&lt;/li&gt;&#xD;&#xA;&lt;li&gt;对于遍历的点,如果在哈希表内,说明其是b&lt;/li&gt;&#xD;&#xA;&lt;li&gt;现在维护的单调栈满足需求&lt;/li&gt;&#xD;&#xA;&lt;li&gt;二分查到的答案再写回相应的位置&lt;/li&gt;&#xD;&#xA;&lt;/ol&gt;&#xD;&#xA;&lt;h2&gt;Code&lt;/h2&gt;&#xD;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-python&#34;&gt;class Solution:    &#xD;&#xA;    def leftmostBuildingQueries(self, heights: List[int], queries: List[List[int]]) -&amp;gt; List[int]:&#xD;&#xA;        n=len(queries)  &#xD;&#xA;        hash={}#记录b对应的a和index&#xD;&#xA;        for i in range(n):&#xD;&#xA;            a=min(queries[i])&#xD;&#xA;            b=max(queries[i])&#xD;&#xA;            if b not in hash:&#xD;&#xA;                hash[b]=[]&#xD;&#xA;            hash[b].append([a,i])&#xD;&#xA;&lt;pre&gt;&lt;code&gt;    #记录右边单调递增&#xD;&#xA;    st=[]&#xD;&#xA;    res=[-1]*n&#xD;&#xA;    for i in range(len(heights)-1,-1,-1):&#xD;&#xA;        h=heights[i]&#xD;&#xA;        while st and h&amp;amp;gt;heights[st[-1]]:&#xD;&#xA;            st.pop()&#xD;&#xA;        st.append(i)&#xD;&#xA;        if i in hash:&#xD;&#xA;            b=i&#xD;&#xA;            for a,index in hash[i]:&#xD;&#xA;                if heights[b]&amp;amp;gt;heights[a] or a==b:&#xD;&#xA;                    res[index]=b&#xD;&#xA;                else:&#xD;&#xA;                    l,r=0,len(st)-1&#xD;&#xA;                    while l&amp;amp;lt;=r:&#xD;&#xA;                        mid=(l+r)//2&#xD;&#xA;                        if heights[st[mid]]&amp;amp;gt;heights[a]:&#xD;&#xA;                            l=mid+1&#xD;&#xA;                        else:&#xD;&#xA;                            r=mid-1&#xD;&#xA;                    if (l-1&amp;amp;lt;0):&#xD;&#xA;                        res[index]=-1&#xD;&#xA;                    else:&#xD;&#xA;                        res[index]=st[l-1]&#xD;&#xA;    return res&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&#xD;&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
			</item>
			<item>
				<title>题解-每棵子树内缺失的最小基因值</title>
				<link>https://noirzh.com/minimum-time-to-eat-all-grains-solution/</link>
				<pubDate>Tue, 07 Nov 2023 15:33:00 +0800</pubDate>
				<guid>https://noirzh.com/minimum-time-to-eat-all-grains-solution/</guid>
				<description>&lt;blockquote&gt;&#xD;&#xA;&lt;p&gt;&lt;a href=&#34;https://leetcode.cn/problems/smallest-missing-genetic-value-in-each-subtree/&#34;&gt;每棵子树内缺失的最小基因值&lt;/a&gt;&lt;/p&gt;&#xD;&#xA;&lt;/blockquote&gt;&#xD;&#xA;&lt;h2&gt;题目简介&lt;/h2&gt;&#xD;&#xA;&lt;p&gt;有一棵根节点为 0 的家族树 ，总共包含 n 个节点，节点编号为 0 到 n – 1 。给你一个下标从 0 开始的整数数组 parents ，其中 parents[i] 是节点 i 的父节点。由于节点 0 是 根 ，所以 parents[0] == -1 。&lt;/p&gt;&#xD;&#xA;&lt;p&gt;总共有 $10^5$ 个基因值，每个基因值都用 闭区间 $[1, 10^5]$ 中的一个整数表示。给你一个下标从 0 开始的整数数组 nums ，其中 nums[i] 是节点 i 的基因值，且基因值互不相同 。&lt;/p&gt;&#xD;&#xA;&lt;p&gt;请你返回一个数组 ans ，长度为 n ，其中 ans[i] 是以节点 i 为根的子树内 缺失 的 最小 基因值。&lt;/p&gt;&#xD;&#xA;&lt;p&gt;节点 x 为根的 子树 包含节点 x 和它所有的后代节点。&lt;/p&gt;&#xD;&#xA;&lt;h2&gt;思路&lt;/h2&gt;&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;在概念上与41. 缺失的第一个正数题类似,都是找数,由于本题没有要求O(1)O(1)O(1)的空间复杂度,所以用哈希表是可能的&lt;/li&gt;&#xD;&#xA;&lt;li&gt;与数组中缺失的第一个正数类似的是,如果一棵树的节点不包括1,则以该树的任意节点为根的的子树都缺少1,这是最简单的情况&lt;/li&gt;&#xD;&#xA;&lt;li&gt;对于子节点有1的才是重要讨论的情况&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;h2&gt;解题方法&lt;/h2&gt;&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;注意到需要处理的只是根节点到基因值为1的这一段的每个节点  &#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;注意到此时讨论的只是一条链&lt;/li&gt;&#xD;&#xA;&lt;li&gt;其他的节点的缺失值一定为1&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;/li&gt;&#xD;&#xA;&lt;li&gt;可以用哈希表记录以该节点为根的子树包含的所有基因值,然后再每个节点都遍历一下&lt;/li&gt;&#xD;&#xA;&lt;li&gt;上述复杂度很高,再仔细观察节点的哈希表的形式,可以知道父节点的哈希表是所有子节点的合集加上自己的基因数&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;所以我们只需要自底向上遍历,维护一个哈希表就可以了&lt;/li&gt;&#xD;&#xA;&lt;li&gt;注意到父节点缺失的值不可能比子树缺失的还小,所以也需要维护一个基因数&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;/li&gt;&#xD;&#xA;&lt;li&gt;时间复杂度:$O(n)$&lt;/li&gt;&#xD;&#xA;&lt;li&gt;空间复杂度:$O(n)$&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;h2&gt;代码&lt;/h2&gt;&#xD;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-python&#34;&gt;class Solution:&#xD;&#xA;    def smallestMissingValueSubtree(self, parents: List[int], nums: List[int]) -&amp;gt; List[int]:&#xD;&#xA;        n=len(parents)&#xD;&#xA;        res=[1]*n #默认最有可能缺1&#xD;&#xA;        if 1 not in nums:&#xD;&#xA;            return res&#xD;&#xA;        graph=[[]for _ in range(n)]&#xD;&#xA;        for i in range(1,n):&#xD;&#xA;            graph[parents[i]].append(i)&#xD;&#xA;&lt;pre&gt;&lt;code&gt;    visited=set()  &#xD;&#xA;    def dfs(index):&#xD;&#xA;        visited.add(nums[index])&#xD;&#xA;        for child in graph[index]:&#xD;&#xA;            if nums[child] not in visited:&#xD;&#xA;                dfs(child)&#xD;&#xA;&#xD;&#xA;    root=nums.index(1) #找分界点&#xD;&#xA;    now=2&#xD;&#xA;    while root&amp;amp;gt;=0: #自底向上递归查找&#xD;&#xA;        dfs(root)&#xD;&#xA;        while now in visited:&#xD;&#xA;            now+=1&#xD;&#xA;        res[root]=now&#xD;&#xA;        root=parents[root]&#xD;&#xA;    return res&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&#xD;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;h2&gt;其他&lt;/h2&gt;&#xD;&#xA;&lt;p&gt;这个理论上不能用与41题类似的将数组本身化为哈希表的操作,不然代码的复杂性很高,而且也不好理解&lt;/p&gt;</description>
			</item>
			<item>
				<title>题解-最长相邻不相等子序列 II</title>
				<link>https://noirzh.com/solution-longest-unequal-adjacent-groups-subsequence-ii/</link>
				<pubDate>Sun, 15 Oct 2023 02:42:00 +0800</pubDate>
				<guid>https://noirzh.com/solution-longest-unequal-adjacent-groups-subsequence-ii/</guid>
				<description>&lt;blockquote&gt;&#xD;&#xA;&lt;p&gt;Problem:&lt;a href=&#34;https://leetcode.cn/problems/longest-unequal-adjacent-groups-subsequence-ii/description/&#34;&gt;最长相邻不相等子序列&lt;/a&gt;&lt;/p&gt;&#xD;&#xA;&lt;/blockquote&gt;&#xD;&#xA;&lt;h2&gt;&lt;strong&gt;题目&lt;/strong&gt;&lt;/h2&gt;&#xD;&#xA;&lt;p&gt;给你一个整数 &lt;code&gt;n&lt;/code&gt; 和一个下标从 &lt;strong&gt;0&lt;/strong&gt; 开始的字符串数组 &lt;code&gt;words&lt;/code&gt; ，和一个下标从 &lt;strong&gt;0&lt;/strong&gt; 开始的数组 &lt;code&gt;groups&lt;/code&gt; ，两个数组长度都是 &lt;code&gt;n&lt;/code&gt; 。&lt;/p&gt;&#xD;&#xA;&lt;p&gt;两个长度相等字符串的 &lt;strong&gt;汉明距离&lt;/strong&gt; 定义为对应位置字符 &lt;strong&gt;不同&lt;/strong&gt; 的数目。&lt;/p&gt;&#xD;&#xA;&lt;p&gt;你需要从下标 &lt;code&gt;[0, 1, ..., n - 1]&lt;/code&gt; 中选出一个 &lt;strong&gt;最长子序列&lt;/strong&gt; ，将这个子序列记作长度为 &lt;code&gt;k&lt;/code&gt; 的 &lt;code&gt;[i&lt;sub&gt;0&lt;/sub&gt;, i&lt;sub&gt;1&lt;/sub&gt;, ..., i&lt;sub&gt;k - 1&lt;/sub&gt;]&lt;/code&gt; ，它需要满足以下条件：&lt;/p&gt;&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;&lt;strong&gt;相邻&lt;/strong&gt; 下标对应的 &lt;code&gt;groups&lt;/code&gt; 值 &lt;strong&gt;不同&lt;/strong&gt;。即，对于所有满足 &lt;code&gt;0 &amp;lt; j + 1 &amp;lt; k&lt;/code&gt; 的 &lt;code&gt;j&lt;/code&gt; 都有 &lt;code&gt;groups[i&lt;sub&gt;j&lt;/sub&gt;] != groups[i&lt;sub&gt;j + 1&lt;/sub&gt;]&lt;/code&gt; 。&lt;/li&gt;&#xD;&#xA;&lt;li&gt;对于所有 &lt;code&gt;0 &amp;lt; j + 1 &amp;lt; k&lt;/code&gt; 的下标 &lt;code&gt;j&lt;/code&gt; ，都满足 &lt;code&gt;words[i&lt;sub&gt;j&lt;/sub&gt;]&lt;/code&gt; 和 &lt;code&gt;words[i&lt;sub&gt;j + 1&lt;/sub&gt;]&lt;/code&gt; 的长度 &lt;strong&gt;相等&lt;/strong&gt; ，且两个字符串之间的 &lt;strong&gt;汉明距离&lt;/strong&gt; 为 &lt;code&gt;1&lt;/code&gt; 。&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;p&gt;请你返回一个字符串数组，它是下标子序列 &lt;strong&gt;依次&lt;/strong&gt; 对应 &lt;code&gt;words&lt;/code&gt; 数组中的字符串连接形成的字符串数组。如果有多个答案，返回任意一个。&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&lt;strong&gt;子序列&lt;/strong&gt; 指的是从原数组中删掉一些（也可能一个也不删掉）元素，剩余元素不改变相对位置得到的新的数组。&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt;&lt;code&gt;words&lt;/code&gt; 中的字符串长度可能 &lt;strong&gt;不相等&lt;/strong&gt; 。&lt;/p&gt;</description>
			</item>
			<item>
				<title>题解-有向图访问计数,一个有向基环树的简单应用</title>
				<link>https://noirzh.com/count-visited-nodes-in-a-directed-graph-solutions/</link>
				<pubDate>Sat, 14 Oct 2023 08:27:00 +0800</pubDate>
				<guid>https://noirzh.com/count-visited-nodes-in-a-directed-graph-solutions/</guid>
				<description>&lt;p&gt;&amp;gt; Problem: &lt;a href=&#34;https://leetcode.cn/problems/count-visited-nodes-in-a-directed-graph/description/&#34;&gt;2876. 有向图访问计数&lt;/a&gt;&lt;/p&gt;&#xD;&#xA;&lt;h2&gt;&lt;strong&gt;思路&lt;/strong&gt;&lt;/h2&gt;&#xD;&#xA;&lt;p&gt;– 注意到这个图一定有环,而且每个点的出度都为1&lt;/p&gt;&#xD;&#xA;&lt;p&gt;– 由题意可知从任意节点出发其都能访问到相关的环&lt;/p&gt;&#xD;&#xA;&lt;p&gt;– 答案只分为两个情况:&lt;/p&gt;&#xD;&#xA;&lt;p&gt;    – 点在环上,此时能访问的点只有环上的点,不可能出环,答案为环的长度&lt;/p&gt;&#xD;&#xA;&lt;p&gt;    – 点在环外,除了环本身之外,其能访问本节点到环的几个节点,答案为环的长度加上其到环的距离&lt;/p&gt;&#xD;&#xA;&lt;p&gt;– 注意到可能有多个环相互独立存在,但是不可能出现两个环连通,所以几个图之间互相并不干扰&lt;/p&gt;&#xD;&#xA;&lt;h2&gt;&lt;strong&gt;解题方法&lt;/strong&gt;&lt;/h2&gt;&#xD;&#xA;&lt;p&gt;1. 由以上思路得到基本想法,遍历解决每一个单独的环即可&lt;/p&gt;&#xD;&#xA;&lt;p&gt;2. 选择一个没有访问的节点,开始访问,其一定能进入环&lt;/p&gt;&#xD;&#xA;&lt;p&gt;    1. 记录初次访问访问点的深度&lt;/p&gt;&#xD;&#xA;&lt;p&gt;    2. 判断是否已经入环的方法就是判断该节点是否已经访问过&lt;/p&gt;&#xD;&#xA;&lt;p&gt;3. 对于当前点已经访问过有两种情况:&lt;/p&gt;&#xD;&#xA;&lt;p&gt;    1. 当前节点在之前的旧图上就访问过:此时根据访问深度加上之前已经得出点的答案来更新答案数组&lt;/p&gt;&#xD;&#xA;&lt;p&gt;    2. 当前节点是在这个新图上访问两次:此时第二次访问深度减去节点访问深度就是环的长度,更新环上节点的答案,环外带上的节点根据访问深度加环的长度更新&lt;/p&gt;&#xD;&#xA;&lt;p&gt;4. 持续上述操作直到所有节点都访问过,因为我们每次都将单个有环图的所有节点处理,所以每个节点都已经处理&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&amp;gt; 时间复杂度,$O(n)$&lt;/p&gt;&#xD;&#xA;&lt;p&gt;&amp;gt; 空间复杂度,$O(n)$&lt;/p&gt;&#xD;&#xA;&lt;h2&gt;代码&lt;/h2&gt;&#xD;&#xA;&lt;p&gt;,对于这种问题应该可以补一个快慢指针法,但是此处没有做&lt;/p&gt;&#xD;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-python&#34;&gt;class Solution:&#xD;&#xA;    def countVisitedNodes(self, edges: List[int]) -&amp;gt; List[int]:&#xD;&#xA;        n=len(edges)&#xD;&#xA;        res=[-1]*n&#xD;&#xA;        visited=set()&#xD;&#xA;        for i in range(n):&#xD;&#xA;            if i in visited:&#xD;&#xA;                continue&#xD;&#xA;            now=begin=i #记录begin就不用做反图,直接顺序遍历就能找到答案&#xD;&#xA;            tmp=dict()#记录此次遍历的时候访问的点&#xD;&#xA;            index=0&#xD;&#xA;            while now not in visited:&#xD;&#xA;                tmp[now]=index&#xD;&#xA;                visited.add(now)&#xD;&#xA;                index+=1&#xD;&#xA;                now=edges[now]&#xD;&#xA;            # 此时我们访问了的图有三种可能,一条带,一个环,一个有带的环&#xD;&#xA;            # 后两种可能都是如下解法&#xD;&#xA;            if now in tmp:&#xD;&#xA;                #此时tmp[now]长度为点到环的长度&#xD;&#xA;                belt=dict()&#xD;&#xA;                circle=set()&#xD;&#xA;                length=tmp[now]&#xD;&#xA;                now=begin&#xD;&#xA;                while length&amp;gt;0:&#xD;&#xA;                    belt[now]=length&#xD;&#xA;                    length-=1&#xD;&#xA;                    now=edges[now]&#xD;&#xA;                while now not in circle:&#xD;&#xA;                    circle.add(now)&#xD;&#xA;                    now=edges[now]&#xD;&#xA;                r=len(circle)#环的长度&#xD;&#xA;                for u in tmp:&#xD;&#xA;                    res[u]=r if u in circle else r+belt[u]&#xD;&#xA;            # 第一种可能是比较好处理的&#xD;&#xA;            else:&#xD;&#xA;                #说明连接到了之前的有向基环树上,直接与已经访问的点相加即可&#xD;&#xA;                length=index&#xD;&#xA;                baseLength=res[now]&#xD;&#xA;                now=begin&#xD;&#xA;                while length&amp;gt;0:&#xD;&#xA;                    res[now]=baseLength+length&#xD;&#xA;                    now=edges[now]&#xD;&#xA;                    length-=1&#xD;&#xA;&lt;pre&gt;&lt;code&gt;    return res&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&#xD;&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
			</item>
			<item>
				<title>题解-哈希表,用输入流实现C&#43;&#43;的split函数</title>
				<link>https://noirzh.com/reward-top-k-students-solution/</link>
				<pubDate>Wed, 11 Oct 2023 06:07:00 +0800</pubDate>
				<guid>https://noirzh.com/reward-top-k-students-solution/</guid>
				<description>&lt;blockquote&gt;&#xD;&#xA;&lt;p&gt;题目:&lt;a href=&#34;https://leetcode.cn/problems/reward-top-k-students/description/&#34; rel=&#34;noopener noreferrer&#34; target=&#34;_blank&#34;&gt;奖励最顶尖的 K 名学生&lt;/a&gt;&lt;/p&gt;&#xD;&#xA;&lt;/blockquote&gt;&#xD;&#xA;&lt;h2&gt;题目描述&lt;/h2&gt;&#xD;&#xA;&lt;p&gt;给你两个字符串数组 positive_feedback 和 negative_feedback ，分别包含表示正面的和负面的词汇。不会 有单词同时是正面的和负面的。&lt;/p&gt;&#xD;&#xA;&lt;p&gt;一开始，每位学生分数为 0 。每个正面的单词会给学生的分数 加 3 分，每个负面的词会给学生的分数 减  1 分。&lt;/p&gt;&#xD;&#xA;&lt;p&gt;给你 n 个学生的评语，用一个下标从 0 开始的字符串数组 report 和一个下标从 0 开始的整数数组 student_id 表示，其中 student_id[i] 表示这名学生的 ID ，这名学生的评语是 report[i] 。每名学生的 ID 互不相同。&lt;/p&gt;&#xD;&#xA;&lt;p&gt;给你一个整数 k ，请你返回按照得分 从高到低 最顶尖的 k 名学生。如果有多名学生分数相同，ID 越小排名越前。&lt;/p&gt;&#xD;&#xA;&lt;h2&gt;思路&lt;/h2&gt;&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;题目不难,只需要对比各个词出现次数就可以&lt;/li&gt;&#xD;&#xA;&lt;li&gt;对于不同语言来说上面的可能有一定难度&lt;/li&gt;&#xD;&#xA;&lt;li&gt;所以写了一版C++的split(是用输入流实现的)&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;h2&gt;代码&lt;/h2&gt;&#xD;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-cpp&#34;&gt;class Solution {&#xD;&#xA;public:&#xD;&#xA;  vector&amp;lt;int&amp;gt; topStudents(vector&amp;lt;string&amp;gt;&amp;amp; positive_feedback, vector&amp;lt;string&amp;gt;&amp;amp; negative_feedback, vector&amp;lt;string&amp;gt;&amp;amp; report, vector&amp;lt;int&amp;gt;&amp;amp; student_id, int k) {&#xD;&#xA;      unordered_map&amp;lt;string,int&amp;gt;score;&#xD;&#xA;      vector&amp;lt;pair&amp;lt;int,int&amp;gt;&amp;gt;list;//直接嵌套vector的时间效率不如pair&#xD;&#xA;      for (auto word:positive_feedback) score[word]=3;&#xD;&#xA;      for (auto word:negative_feedback) score[word]=-1;&#xD;&#xA;      for (int i=0;i&amp;lt;student_id.size();i++){&#xD;&#xA;          string words=report[i];&#xD;&#xA;          int id=student_id[i];&#xD;&#xA;          int s=0;&#xD;&#xA;          string key;&#xD;&#xA;          istringstream is(words);//将字符转成输入流然后操作&#xD;&#xA;          while(getline(is,key,&#39; &#39;)){&#xD;&#xA;              if (score.count(key))&#xD;&#xA;                  //key不存在时int默认为0,但是那样效率不&#xD;&#xA;                  s+=score[key];如判断高&#xD;&#xA;          }&#xD;&#xA;          list.emplace_back(make_pair(id,s));&#xD;&#xA;      }&#xD;&#xA;      sort(list.begin(),list.end(),[&amp;amp;](const pair&amp;lt;int,int&amp;gt;a,const pair&amp;lt;int,int&amp;gt;b){&#xD;&#xA;          return a.second&amp;gt;b.second ||(a.second==b.second&amp;amp;&amp;amp;a.first&amp;lt;b.first);&#xD;&#xA;      });&#xD;&#xA;      vector&amp;lt;int&amp;gt;res;&#xD;&#xA;      for (int i=0;i&amp;lt;k;i++){&#xD;&#xA;          res.emplace_back(list[i].first);&#xD;&#xA;      }&#xD;&#xA;      return res;&#xD;&#xA;&lt;p&gt;}&#xA;};&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;</description>
			</item>
			<item>
				<title>题解-英雄的力量</title>
				<link>https://noirzh.com/solution-power-of-heros/</link>
				<pubDate>Tue, 01 Aug 2023 06:31:49 +0800</pubDate>
				<guid>https://noirzh.com/solution-power-of-heros/</guid>
				<description>&lt;blockquote&gt;&#xD;&#xA;&lt;p&gt;Problem: &lt;a href=&#34;https://leetcode.cn/problems/power-of-heroes/description/&#34;&gt;2681. 英雄的力量&lt;/a&gt;&lt;/p&gt;&#xD;&#xA;&lt;/blockquote&gt;&#xD;&#xA;&lt;h2&gt;题目描述&lt;/h2&gt;&#xD;&#xA;&lt;p&gt;给你一个下标从&lt;strong&gt;0&lt;/strong&gt;开始的整数数组&lt;code&gt;nums&lt;/code&gt;，它表示英雄的能力值。如果我们选出一部分英雄，这组英雄的&lt;strong&gt;力量&lt;/strong&gt;定义为：&lt;/p&gt;&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;&lt;strong&gt;&lt;code&gt;i&lt;sub&gt;0&lt;/sub&gt;&lt;/code&gt; ，&lt;code&gt;i&lt;sub&gt;1&lt;/sub&gt;&lt;/code&gt; ，… &lt;code&gt;i&lt;sub&gt;k&lt;/sub&gt;&lt;/code&gt;&lt;/strong&gt; 表示这组英雄在数组中的下标。那么这组英雄的力量为 &lt;code&gt;&lt;strong&gt;max(nums[i&lt;sub&gt;0&lt;/sub&gt;],nums[i&lt;sub&gt;1&lt;/sub&gt;] ... nums[i&lt;sub&gt;k&lt;/sub&gt;])&lt;sup&gt;2&lt;/sup&gt; * min(nums[i&lt;sub&gt;0&lt;/sub&gt;],nums[i&lt;sub&gt;1&lt;/sub&gt;] ... nums[i&lt;sub&gt;k&lt;/sub&gt;])&lt;/strong&gt;&lt;/code&gt; 。&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;p&gt;请你返回所有可能的&lt;strong&gt;非空&lt;/strong&gt;英雄组的&lt;strong&gt;力量&lt;/strong&gt;之和。由于答案可能非常大，请你将结果对&lt;code&gt;&lt;strong&gt;10&lt;sup&gt;9 &lt;/sup&gt;+ 7&lt;/strong&gt;&lt;/code&gt;&lt;strong&gt;取余。&lt;/strong&gt;&lt;/p&gt;&#xD;&#xA;&lt;h2&gt;思路&lt;/h2&gt;&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;选取与顺序无关先排序&lt;/li&gt;&#xD;&#xA;&lt;li&gt;接下来只要枚举所有子序列的最大值的平方和最小值的乘积之和&lt;/li&gt;&#xD;&#xA;&lt;li&gt;注意到只和最大值和最小值有关&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;h2&gt;解题方法&lt;/h2&gt;&#xD;&#xA;&lt;ol&gt;&#xD;&#xA;&lt;li&gt;确定了子序列的最大值之后,我们只需要确定子序列里面各个值最小值出现了几次&lt;/li&gt;&#xD;&#xA;&lt;li&gt;也就是确定排序后的$nums[i]$必选且为最大值时,我们假设此时在答案中与除自身之外他的平方相乘的所有值之和为$pre_i$,此时有答案$res_i=nums[i]^2*(pre_i+nums[i])$&lt;/li&gt;&#xD;&#xA;&lt;li&gt;不去管$pre_i$现在为多少,我们假设现在要选取的是$nums[i+1]$为最大值,则注意到对于子序列&#xD;&#xA;&lt;ol&gt;&#xD;&#xA;&lt;li&gt;如果不选$ nums[i] $,$ pre_i$也会和$nums[i+1]$相乘&lt;/li&gt;&#xD;&#xA;&lt;li&gt;如果选取$nums[i]$,对于所有$nums[i]$不是最小值的情况,$pre_i$也会和$nums[i+1]$相乘,而$nums[i]$是最小值的情况只有一个(也就是选取$i$和$i+1$两个)&lt;/li&gt;&#xD;&#xA;&lt;/ol&gt;&#xD;&#xA;&lt;/li&gt;&#xD;&#xA;&lt;li&gt;根据以上的两个推理,我们能够得出 $$ \displaystyle res_{i+1}=nums[i+1]^2 \cdot (pre_i \cdot 2+nums[i]+nums[i+1]) \\ pre_{i+1}=pre_i\cdot 2+nums[i] $$&lt;/li&gt;&#xD;&#xA;&lt;li&gt;$res=\displaystyle\sum^{n}_{i=0} res_i $&lt;/li&gt;&#xD;&#xA;&lt;/ol&gt;&#xD;&#xA;&lt;ul&gt;&#xD;&#xA;&lt;li&gt;时间复杂度$O(nlogn)$&lt;/li&gt;&#xD;&#xA;&lt;li&gt;空间复杂度$O(1)$&lt;/li&gt;&#xD;&#xA;&lt;/ul&gt;&#xD;&#xA;&lt;h2&gt;Code&lt;/h2&gt;&#xD;&#xA;&lt;div&gt;&#xD;&#xA;&lt;div&gt;&#xD;&#xA;&lt;div&gt;&lt;div&gt;&#xD;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-python&#34;&gt;class Solution:&#xD;&#xA;    def sumOfPower(self, nums: List[int]) -&amp;gt; int:&#xD;&#xA;        mod=1000000007&#xD;&#xA;        nums.sort()&#xD;&#xA;        pre=0&#xD;&#xA;        res=0&#xD;&#xA;        for num in nums:&#xD;&#xA;            res=(res+(pre+num)*(num**2)&#xD;&#xA;            pre=(pre*2+num&#xD;&#xA;        return res&lt;/code&gt;&lt;/pre&gt;&#xD;&#xA;&lt;/div&gt;&lt;/div&gt;&#xD;&#xA;&lt;/div&gt;&#xD;&#xA;&lt;/div&gt;&#xD;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-python&#34;&gt;class Solution {&#xD;&#xA;public:&#xD;&#xA;    int sumOfPower(vector&amp;lt;int&amp;gt;&amp;amp; nums) {&#xD;&#xA;        const int mod=1e9+7;&#xD;&#xA;        sort(nums.begin(),nums.end());&#xD;&#xA;        int res=0,pre=0;&#xD;&#xA;        for (long num:nums){&#xD;&#xA;            res=(res+(num*nu&#xD;&#xA;            pre=(pre*2+num&#xD;&#xA;        }&#xD;&#xA;        return res;&#xD;&#xA;    }&#xD;&#xA;};&#xD;&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
			</item>
	</channel>
</rss>
