Leetcode刷题第三天-贪心-双指针

738:单调递增

链接:738. 单调递增的数字 - 力扣(LeetCode)

嘶~介个介个恶心心,从后往前遍历,前一个数比当前数大,前一个数-1,当前数变为9

需要注意的是,保证每个9后面全是9

100,第一轮遍历完时90T_T

 1 class Solution:
 2     def monotoneIncreasingDigits(self, n: int) -> int:
 3         if(n<10):   return n
 4         nums=[]
 5         tmp=n
 6         while tmp:
 7             nums.insert(0,tmp%10)
 8             tmp=tmp//10
 9         lens=len(nums)
10         i=lens-1
11         flage=False
12         while i>0:
13             if(nums[i-1]>nums[i]):
14                 nums[i-1]-=1
15                 nums[i]=9
16                 flage=True
17             i-=1
18         n=0
19         start=False
20         for i in range(lens):
21             if(flage and nums[i]==9):
22                 start=True
23             if(start):
24                 n=n*10+9
25             else:
26                 n=n*10+nums[i]
27         return n
monotoneIncreasingDigits

968:监控二叉树

链接:968. 监控二叉树 - 力扣(LeetCode)

吐了,真的吐了,从未见过如次厚颜无耻之题

先是统计了每层节点个数,想按层安装,但是会出现子层节点少于父层节点,若在子层节点安装,还需要计算父-父层,跳不出来了T_T

然后迭代,后序遍历T_T左在前,左空的时候直接安到根上,右丢了,右在前,左空了,又跑根上了

最后递归,俩孩子有一个没有被覆盖,父就要安,俩孩子都被覆盖到了,父歇着就好,等待后续判断要不要安,其他情况父被覆盖,最后返回根的左右俩孩子状态,俩孩子都是0,根安T_T我真的已经哭死了

 1 # Definition for a binary tree node.
 2 # class TreeNode:
 3 #     def __init__(self, val=0, left=None, right=None):
 4 #         self.val = val
 5 #         self.left = left
 6 #         self.right = right
 7 class Solution:
 8     def minCameraCover(self, root: Optional[TreeNode]) -> int:
 9         re=[0]
10         if(self.help(root,re)==0):  re[0]+=1
11         return re[0]
12 
13     def help(self,root,re):
14         if(not root):   return 2
15         left=self.help(root.left,re)
16         right=self.help(root.right,re)
17         #左右都有覆盖,当前什么都不做
18         if(left==2 and right==2):
19             return 0
20         #左右有一个没覆盖,自己有摄像头
21         elif(left==0 or right==0):
22             re[0]+=1
23             return 1
24         else:
25             #左右有一个摄像头,自己被覆盖
26             return 2
minCameraCover

更新迭代做法

利用数组(python没有栈,数组就好)pop()取最后加入数组得元素,按照【根空右左】顺序加入数组,左右节点空不加,在根节点后面加入一个空值作为标记,当从数组种取出得元素为空时,证明他的左右节点已经判断完,需要对当前节点进行判断

 1 # Definition for a binary tree node.
 2 # class TreeNode:
 3 #     def __init__(self, val=0, left=None, right=None):
 4 #         self.val = val
 5 #         self.left = left
 6 #         self.right = right
 7 class Solution:
 8     def minCameraCover(self, root: Optional[TreeNode]) -> int:
 9         if(not root):   return 0
10         sums=0
11         stack=[root]
12         while stack:
13             cur=stack.pop()
14             if(cur):
15                 stack.append(cur)
16                 #插入一个空节点,作为标记,遇到空节点就要开始判断是否安摄像头
17                 stack.append(None)
18                 #左右孩子入栈,空不入
19                 if(cur.right):  stack.append(cur.right)
20                 if(cur.left):   stack.append(cur.left)
21             else:
22                 #遇到空,继续取最后一个,判断自己是否安
23                 cur=stack.pop()
24                 left,right=2,2
25                 if(cur.left):   left=cur.left.val
26                 if(cur.right):  right=cur.right.val
27                 if(left==0 or right==0):
28                     sums+=1
29                     cur.val=1
30                 elif(left==2 and right==2):
31                     cur.val=0
32                     #栈空,说明到最后一个根节点,左右孩子被覆盖但是没有摄像头,自己没有被覆盖,所以自己还要安一个
33                     if(not stack):  sums+=1
34                 else:
35                     cur.val=2
36         return sums
stack

 

不行了,需要换个脑子了,开始双指针之旅

167:两个数之和

链接:167. 两数之和 II - 输入有序数组 - 力扣(LeetCode)

(⊙﹏⊙)就两头开始加

 1 class Solution:
 2     def twoSum(self, numbers: List[int], target: int) -> List[int]:
 3         if(not numbers):    return numbers
 4         left,right=0,len(numbers)-1
 5         while True:
 6             if(left==right):    break
 7             if(numbers[left]+numbers[right]==target):   return [left+1,right+1]
 8             elif(numbers[left]+numbers[right]>target):  right-=1
 9             else:   left+=1
10         return []
11 
12             
twoSum

142:环形链表

链接:142. 环形链表 II - 力扣(LeetCode)

俩个指针,快的每次走两步,慢的每次走一步,链表有环,快的会再比慢的多走n个环的距离时相遇(跑步套圈)

找环的入口:从头再来一个指针3,也是每次都走一步,指针3和慢指针相遇的时候,比慢指针少走了一个环,相遇位置就是环口

 1 # Definition for singly-linked list.
 2 # class ListNode:
 3 #     def __init__(self, x):
 4 #         self.val = x
 5 #         self.next = None
 6 
 7 class Solution:
 8     def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
 9         if(not head):   return None
10         start,link=head,head
11         while link and link.next:
12             link=link.next.next
13             start=start.next
14             if(link==start):
15                 start=head
16                 while start!=link:
17                     start=start.next
18                     link=link.next
19                 return link
20         return None
21 
22     
detectCycle

76:最小覆盖字串

链接:76. 最小覆盖子串 - 力扣(LeetCode)

更新更新,把一坨更新了一下,终于可以看清了T_T

 1 class Solution(object):
 2     def minWindow(self,s,t):
 3         if(not s):  return ""
 4         #t长度,要找到得字符得个数
 5         lent=len(t)
 6         lens=len(s)
 7         if(lens<lent):  return ""
 8         #记录t中每个字母出现得频率
 9         flage={x:t.count(x) for x in t}
10         left,minleft,minright=0,-1,lens
11         for right in range(lens):
12             #遍历s,开始移动右边界,如果当前得字符在t中,对应频率数组-1,如果频率大于0,要找得字符个数-1
13             if(s[right] in t):
14                 flage[s[right]]-=1
15                 if(flage[s[right]]>=0): lent-=1
16             #要找得字符个数为0时,当前[left,right]范围内包含全部得t中字符,闭区间
17             if(lent==0):
18                 while left<=right:
19                     #开始移动左边界,如果当前字符在t中,并且lent==0,表示为当前满足题意左边界最大值,判断当前窗口和要窗口大小,谁小取谁,并且频率数组+1,表示左边界开始移动,目标窗口内得字符个数减少
20                     if(s[left] in t):
21                         if(minright-minleft>right-left and lent==0):
22                             minright=right
23                             minleft=left
24                         flage[s[left]]+=1
25                         #当字符频率大于0时,表示当前窗口缺少这个字符,要找得字符长度+1
26                         if(flage[s[left]]>0): lent+=1
27                     left+=1
28                     #要找得字符个数大于0,结束循环
29                     if(lent>0): break
30         #右边界为s长度,表示没有合适得长度
31         if(minright==lens): return ""
32         return s[minleft:minright+1]
minWindow

 

posted @ 2024-01-24 18:13  小小小茹茹  阅读(9)  评论(0编辑  收藏  举报