lc marathon 7.21

814. 二叉树剪枝

巧妙地利用 二叉树重建 + 后缀遍历

从下往上一点点判断,一点点删除

太强了 太优美了

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def pruneTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if root==None:
            return None
        root.left=self.pruneTree(root.left)
        root.right=self.pruneTree(root.right)
        if root.left==None and root.right==None and root.val==0:
            return None
        return root
86. 分隔链表

依然是用言语的手术刀,精准编码

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def partition(self, head: ListNode, x: int) -> ListNode:
        dump1 = ListNode(-1)  # 连接比x小的值
        dump2 = ListNode(-2)  # 连接比x大的值
        q1 = dump1  # 指dump1链表结尾
        q2 = dump2  # 指dump2链表结尾
        p = head  # 用来遍历原链表
        # 对于x,默认加到2链
        while p != None:
            if p.val < x:
                q1.next = p  # 连接该节点
                q1 = q1.next  # q1到链表尾部
            elif p.val > x:
                q2.next = p  # 连接该节点
                q2 = q2.next  # q2到链表尾部
            else:  # 相等时候
                q2.next = p
                q2 = q2.next  # q2到链表尾部
            p = p.next  # p 往后走

        # 最后 都要断链
        q1.next = None
        q2.next = None

        q1.next = dump2.next

        return dump1.next
//C++最简洁的二分法分类讨论
//每次二分,左半部分和右半部分至少有一边是有序的,以此为条件可以分成两种情况:
//1、左半边是有序的
//(1) target落在左半边
//(2) otherwise
//2、右半边是有序的
//(1) target落在右半边
//(2) otherwise
//综上所述,一共两种可能性,这两种情况各自又有两种可能性,代码如下:
bool search(vector<int>& nums, int target) {
        int l = 0, r = nums.size()-1;
        while(l<=r){
            //处理重复数字
            while(l<r&&nums[l]==nums[l+1]) ++l;
            while(l<r&&nums[r]==nums[r-1]) --r;
            int mid = l+(r-l)/2;
            if(nums[mid]==target) return true;
            //左半部分有序
            if(nums[mid]>=nums[l]){
                if(target<nums[mid]&&target>=nums[l]) r = mid-1;//target落在左半边
                else l = mid+1;
            }
            else{//右半部分有序
                if(target>nums[mid]&&target<=nums[r]) l = mid+1;//target落在右半边
                else r = mid-1;
            }
        }
        return false;
    }
435. 无重叠区间

记录一下大佬的思想: 贪心算法,按照起点排序:选择结尾最短的,后面才可能连接更多的区间(如果两个区间有重叠,应该保留结尾小的) 把问题转化为最多能保留多少个区间,使他们互不重复,则按照终点排序,每个区间的结尾很重要,结尾越小,则后面越有可能容纳更多的区间。
在这里插入图片描述

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        def so(x1,x2):
            if x1[0]<=x2[0]:
                return -1
            else:
                return 1

        intervals=sorted(intervals,key=cmp_to_key(so))
        ans=0
        nums=intervals
        for index in range(1,len(intervals)):
            if nums[index][0] >=nums[index-1][1]:
                continue
            if nums[index][0]<nums[index-1][1]:
                if nums[index][1]<=nums[index-1][1]:
                    ans+=1
                    continue
                else:
                    nums[index][0]=nums[index-1][0]
                    nums[index][1]=nums[index-1][1]
                    ans+=1
                    continue
        return ans
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值