2022-8-23力扣刷题

本文档分享了解决LeetCode题目,包括矩阵操作使之成为棋盘形式,寻找数组中第k个缺失正整数,判断二叉搜索树峰谷数量,以及查找二叉搜索树中和为目标值的节点对。通过算法思路解析和代码实现,提升编程技巧。
摘要由CSDN通过智能技术生成

 系列文章为每日leetcode刷题记录,从算法思路到代码,如果实践充分提供python和java两种答案。废话不多说,直接开整。

题目: 

 每日一题+随机三题

题目链接难度
力扣782:2022-08-23每日一题困难
力扣1539简单
力扣2210简单
 力扣653简单

ww 

解题思路

 1.题目描述:矩阵只包含01,只进行整行整列变换,目标矩阵为“棋盘”。

1.1   根据“棋盘”发现,无论是整行移动还是整列移动,移动以后原本与首行首列相同的依旧相同,不同的依旧不同。并且不同时行中或列中每一个数字都与首行首列不同,如:首行1010,不同的为0101。可知初始矩阵其他行与首行要么相同要么取反。此条用于检测矩阵是否可以进行变化得到棋盘。

1.2   根据“棋盘”当棋盘维度为偶数时每行中1和0个数相同,且与首行相同的个行数与不同的行数相等,当棋盘维度为奇数时,0和1的个数相差1。此条用于求取最小移动次数。且与首行不同的行数与相同的行数差1

class Solution:
    def movesToChessboard(self, board):
        # 矩阵维度
        n = len(board)
        #记录首行首列
        firstRow , firstCol = 0, 0
        # |=按位或运算, << 左移
        # 得到对应行的二进制表达
        for i in range(n):
            firstRow |= board[0][i] << i
            firstCol |= board[i][0] << i
        # ^异或运算,取不同于首行的行数字
        reverseRow = ((1<<n) - 1) ^ firstRow
        reverseCol = ((1<<n) - 1) ^ firstCol
        # 用于记录相同与第一行的行数
        rowCnt = colCnt = 0
        for i in range(n):
            currRow = currCol = 0
            for j in range(n):
                currRow |= board[i][j] << j
                currCol |= board[j][i] << j
            if currRow != firstRow and currRow != reverseRow \
                or currCol != firstCol and currCol != reverseCol:
                return -1
            rowCnt += currRow == firstRow
            colCnt += currCol == firstCol
        # mask 行或者列, count 与首行相同的个数
        def getMoves(mask, count):
            # 二进制表达中1的个数
            ones = mask.bit_count()
            if n & 1:
                if abs(n - 2*ones) !=1 or abs(n- 2*count) != 1:
                    return -1
                # 0比1多一个的情况,首位先放0然后在放一
                if ones == n // 2:
                    # 0xAAAAAAAA 的二进制1010 1010 1010 1010 1010 1010 1010 1010
                    return n // 2 -(mask & 0xAAAAAAAA).bit_count()
                else:
                    # 0x55555555 的二进制为0101 0101 0101 0101 0101 0101 0101 0101
                    return (n+1) // 2 - (mask & 0x55555555).bit_count()
            # 偶数行
            else:
                if ones !=n // 2 or count != n // 2:
                    return -1
                count0 = n // 2 -(mask & 0xAAAAAAAA).bit_count()
                count1 = (n+1) // 2 - (mask & 0x55555555).bit_count()
                return min(count0, count1)

        rowMoves = getMoves(firstRow, rowCnt)
        colMoves = getMoves(firstCol, colCnt)
        return -1 if rowMoves ==-1 and colMoves == -1 else rowMoves + colMoves

        

2.给你一个 严格升序排列 的正整数数组 arr 和一个整数 k 。请你找到这个数组里第 k 个缺失的正整数。

根据数字范围声明一个数组,移除给出的所有数字,返回第k个。

class Solution:
    def findKthPositive(self, arr: List[int], k: int) -> int:
        res_list = [i for i in range(1,2001)]
        for item in arr:
            res_list.remove(item)
        return res_list[k-1]

3.给你一个下标从 0 开始的整数数组 nums 。如果两侧距 i 最近的不相等邻居的值均小于 nums[i] ,则下标 i 是 nums 中,某个峰的一部分。类似地,如果两侧距 i 最近的不相等邻居的值均大于 nums[i] ,则下标 i 是 nums 中某个谷的一部分。对于相邻下标 i 和 j ,如果 nums[i] == nums[j] , 则认为这两下标属于 同一个 峰或谷。

注意,要使某个下标所做峰或谷的一部分,那么它左右两侧必须 都 存在不相等邻居。

返回 nums 中峰和谷的数量。

删除重复数字,找波峰波谷

class Solution:
    def countHillValley(self, nums: List[int]) -> int:
        i = 0
        n =len(nums)
        res = 0
        while(i<n-1):
            if nums[i] == nums[i+1]:
                nums.pop(i)
                n -= 1
            else:
                i +=1
        for j in range(1, n-1):
            if nums[j] >nums[j-1] and nums[j] > nums[j+1] or \
                nums[j] < nums[j-1] and nums[j] < nums[j+1]:
                res +=1
        return res

 4.给定一个二叉搜索树 root 和一个目标结果 k,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true

中序遍历,查找

class Solution:
    def findTarget(self, root: Optional[TreeNode], k: int) -> bool:
        mid_list = []
        def midSearch(root):
            if root.left:
                midSearch(root.left)
            mid_list.append(root.val)
            if root.right:
                midSearch(root.right)
        
        midSearch(root)
        n = len(mid_list)
        for i in range(n):
            for j in range(n-1, i, -1):
                if (k-mid_list[i]) == mid_list[j]:
                    return True
        return False

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值