leetcode专项刷题_数组(1)_0~n-1中缺失的数字/高度检查器/最长连续递增序列/拼写单词/元素替换

感觉要学,要看的东西太多了。但是这其中,算法也一定是核心中的核心,于是决定有时间就刷刷题,研究了下,个人觉得照题的类型来可能效果要好些,这样可能对于某一种的题型就上手更快。奔跑吧,少年~~

0~n-1中缺失的数字

题目描述

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字

代码实现

# 预期: [0,1,2,3,4,5,6,7,9] >> 8;  [0,1,3] >> 2

# 暴力法,创造遍历的条件
# 思路: 手动构造有序表,因为缺少一个值,所以要构造的是nums+1个数的值,然后和数据按照索引位置对比就行了
class Solution:
    def missingNumber(self, nums):
        base = [i for i in range(len(nums) + 1)]
        for i in range(len(nums)):
            if nums[i] != base[i]:
                return base[i]
        if base:
            return base[-1]

# 二分法
# 思路: 通过画图可以分析出只有两种情况,
# 1.mid = (right + left) // 2,(索引大小和索引值相等则代表当前索引之前的数字是不缺失的,那么继续在索		 引值后面的位置搜索即可)
# 2.nums[mid] > mid,则代表着缺少的值在当前索引的前面位置,所以往前面去找就行了
# 结果:最后返回边界值即可
class Solution:
    def missingNumber(self, nums):
        left, right = 0, len(nums)
        while left < right:
            mid = (right + left) // 2
            if nums[mid] == mid:
                left += 1
            elif nums[mid] > mid:
                right -= 1
        return right

高度检查器

题目描述

给一个无序列表,那么同时假设也存在这么一列表,是这个无序列表的有序展示,那么把无序表和有序表的相同索引位置进行对比的话,有几个不一样(数据大小为1-100之间)

代码实现

# 预期: 	  heights = [1, 1, 4, 2, 1, 3] >> 3
# 解释: 排序之后的数组为 [1, 1, 1, 2, 3, 4], 那么发现只有索引位置为0,1和3的位置一模一样,所以返回3,代表				3个位置放置的位置错误

# 方法一: 基于桶排序
class Solution:
    def heightChecker(self, heights):
        count = 0
        
        # 因为假设数据大小为1-100,则生成101个桶,目的是让每个桶存放和索引值相同的数值,(比如1号桶存放数值     					等于1的数据),并计算每个桶内数据的个数
        baes_list = [0 for _ in range(101)]
        for num in heights:
            baes_list[num] += 1

        # 将桶内不等于1的数据依次添加到列表中,那么这个就是无序表排序之后结果
        ret = []
        for index in range(len(baes_list)):
            while baes_list[index] != 0:
                ret.append(index)
                baes_list[index] -= 1
        
        # 对桶排序的结果和原有列表一一进行对比,不对应的位置则是需要调换的次数
        for i in range(len(heights)):
            if heights[i] != ret[i]:
                count += 1
        return count
      
# 方法二: 原理一样,简化了一些步骤
class Solution:
    def heightChecker(self, heights: List[int]) -> int:
        d = [0] * 101
        ans = j = 0
        for i in heights:
            d[i] += 1
        
        for i in range(1, 101):
            while d[i]:
                if heights[j] != i:
                    ans += 1
                j += 1
                d[i] -= 1
        return ans

最长连续递增序列

题目描述

给定一个未经排序的整数数组,找到最长且连续的的递增序列,并返回该序列的长度

代码实现

# 预期: 	  [1,3,5,4,7] >> 3							[2,2,2,2,2] >> 1 (相同值不算递增关系)
# 解释: 最长连续递增序列是 [1,3,5], 长度为3。尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为5和7在 			 原数组里被4隔开。 

# 方法
class Solution:
    def findLengthOfLCIS(self, nums):
        ret = []
        start_index = 0
        for i in range(len(nums) - 1):
						# 统计直到相邻值中后一个值小于前一个值的数据个数,并添加到统计长度列表中
            if nums[i + 1] <= nums[i]:
                end_index = i + 1
                ret.append(end_index - start_index)
                # 保证开始统计的索引值一定是出现当前情况下才开始变化
                start_index = i + 1
        # 如果最后几个数字呈递增状态,那么从开始到最后都为递增状态,于是用总长度减去上一次索引开始的位置/或						者最后一个值小于倒数第二个值
        ret.append(len(nums) - start_index)
        print(ret)
        return max(ret)

拼写单词

题目描述

给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars。

假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌握了这个单词。

注意:每次拼写(指拼写词汇表中的一个单词)时,chars 中的每个字母都只能用一次。

返回词汇表 words 中你掌握的所有单词的 长度之和

代码实现

# words = ["cat","bt","hat","tree"], chars = "atach"  	>>  6    可以形成字符串 "cat" 和 "hat",所以答案是 3 + 3 = 6
# words = ["hello","world","leetcode"], chars = "welldonehoneyr"  >>    10			可以形成字符串 "hello" 和 "world",所以答案是 5 + 5 = 10

# 我的方法(原理一样的,只是官方用了标准库,我知道collections的那个方法,我合计万一不让用标准库呢,所以就用了字典推倒,但是就因为我用了字典推导性能竟然下降了一半,空间使用差不多)
# 思路:
# 1.一看到这题,我就觉得应该是哈希解决,所以第一步先转成了字典,键为字符,值为出现的次数
# 2.然后判断单词是否是charts_dic的子集就可以了,我这里用了个函数判断,个人觉得比较好理解
class Solution:
    def countCharacters(self, words, chars):
        count = 0
        chars_dic = {chars[i]: chars.count(chars[i]) for i in range(len(chars))}
        for word in words:
            word_dic = {word[i]: word.count(word[i]) for i in range(len(word))}
            if self.contrast_dic(chars_dic, word_dic):
                count += len(word)
        return count

    @staticmethod
    def contrast_dic(base_dic, contrast_dic):
        for key in contrast_dic:
          # 只要key不在基础表中或者对应的次数值大于基础表,那么就为False
            if key not in base_dic or contrast_dic[key] > base_dic[key]:
                return False
        return True

# 官方解法
class Solution:
    def countCharacters(self, words: List[str], chars: str) -> int:
        chars_cnt = collections.Counter(chars)
        ans = 0
        for word in words:
            word_cnt = collections.Counter(word)
            for c in word_cnt:
                if chars_cnt[c] < word_cnt[c]:
                    break
            else:
                ans += len(word)
        return ans

将每个元素替换为右侧最大元素

题目描述

给你一个数组 arr ,请你将每个元素用它右边最大的元素替换,如果是最后一个元素,用 -1 替换。

完成所有替换操作后,请你返回这个数组。

代码实现

# 预期: arr = [17,18,5,4,6,1] >>> [18,6,6,6,1,-1]

# 好理解,但是性能不好
class Solution:
    def replaceElements(self, arr):
        # 每一次都从后边的列表中拿最大数据赋值就行了
        for index in range(len(arr) - 1):
            arr[index] = max(arr[index + 1:])
        arr[-1] = -1
        return arr
      
# debug打一遍就理解了 
class Solution(object):
    def replaceElements(self, arr):
        """
        :type arr: List[int]
        :rtype: List[int]
        """
        #倒序比较即可,最后替换两端元素
        rmax = arr[-1]
        for i in range(len(arr)-1, 0, -1):
            temp = arr[i]
            arr[i] = rmax
            rmax = max(rmax, temp)
        arr[0] = rmax
        arr[-1]= -1
        return arr
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值