letcode刷题(2020.01.01--2020.01.10)

1.移除元素(2020.1.1)

题目描述:

给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 

解题思路:

  1. 采用双指针,首先定义快指针j为0,慢指针i为0,传入的数字长度为length
  2. 使用while循环,如果j不小于length,跳出循环
  3. 如果快指针指定元素不等于val,将元素移动到慢指针位置。快慢指针同时加1。否则,快指针加1

代码实现:

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        length = len(nums)
        j = 0
        i = 0
        while j

2.搜索插入位置(2020.1.2)

题目描述:

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

你可以假设数组中无重复元素。

示例 1:

输入: [1,3,5,6], 5
输出: 2
示例 2:

输入: [1,3,5,6], 2
输出: 1
示例 3:

输入: [1,3,5,6], 7
输出: 4
示例 4:

输入: [1,3,5,6], 0
输出: 0

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-insert-position
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

  1. 对于有序列表搜索问题,我们使用二分法进行查找
  2. 首先定义begin、end两个变量,begin为二分开始位置,end为二分结束位置。
  3. 使用while循环,当begin大于end时,说明列表中未找到目标值。如果将目标值插入列表中,所在位置应该为begin
  4. 进入while循环,定义mid变量为(begin+end)//2,判断nums[mid]与taget的关系,等于-返回mid,大于-end=mid-1,小于-begin=mid+1

代码实现:

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        end = len(nums) - 1
        begin = 0
        while begin <= end:
            mid = (begin + end) // 2
            if nums[mid] == target:
                return mid
            elif nums[mid] > target:
                end = mid - 1
            else:
                begin = mid + 1                
        return begin

3.最大子序和(2020.1.3)

题目描述:

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:

输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-subarray
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

  1.  使用贪心算法,把单个数组作为输入来查找最大元素的问题,每一步都选择最佳方法,到最后就是全局的最优方案
  2. 定义变量curr_max、sum_max都等于列表的第一个元素
  3. 遍历列表,每次令curr_max等于curr_max、curr_max+当前元素,两者中最大的值,max_sum等于max_sum、curr_max中最大的值
  4. 循环结束后,得到的max_sum就为连续子数组的最大和

代码实现:

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        n = len(nums)
        curr_max = sum_max = nums[0]
        for i in range(1,n):
            curr_max = max(nums[i], nums[i] + curr_max)
            sum_max = max(sum_max, curr_max)
            print(curr_max,sum_max)
        return sum_max

4.最后一个单词的长度(2020.1.4)

题目描述:

给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度。

如果不存在最后一个单词,请返回 0 。

说明:一个单词是指由字母组成,但不包含任何空格的字符串。

示例:

输入: "Hello World"
输出: 5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/length-of-last-word
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

  1. 首先去除字符串的前后空格,判断字符串如果为空,返回0
  2. 从字符串后面往前遍历,找到第一个为空格的字符,那么空格后的字符串就为最后一个单词,返回其长度
  3. 如果字符串中没有空格,证明该字符串只有一个单词,返回字符串的长度即可

代码实现:

class Solution:
    def lengthOfLastWord(self, s: str) -> int:
        #去除字符串前后空格
        s = s.strip()
        #如果为空,返回0
        if not s:
            return 0
        n = len(s)
        while 0 <= n:
            #查找最后一个空格,返回空格之后的字符串长度
            if s[n-1] == ' ':
                return len(s) - n 
            n -= 1
        #如果字符一个单词,返回传入的字符串长度
        else:
            return len(s)

5.加一(2020.1.5)

题目描述:

给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。

最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。

你可以假设除了整数 0 之外,这个整数不会以零开头。

示例 1:

输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。
示例 2:

输入: [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/plus-one
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

  1. 将整数数组转行成相应的整数
  2. 将整数加1后,转换成字符串
  3. 再将字符串转换成列表

代码实现:

class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        sum = 0
        for i in digits:
            sum = sum*10 + i
        sum = str(sum + 1)
        return list(sum)

6.二进制求和(2020.1.6)

题目描述:

给定两个二进制字符串,返回他们的和(用二进制表示)。

输入为非空字符串且只包含数字 1 和 0。

示例 1:

输入: a = "11", b = "1"
输出: "100"
示例 2:

输入: a = "1010", b = "1011"
输出: "10101"

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-binary
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

  1. 使用int方法将二进制字符串转换为十进制整型,再进行相加
  2. 将相加的结果使用bin方法转换为二进制字符串,返回结果

代码实现:

class Solution:
    def addBinary(self, a: str, b: str) -> str:
        c = int(a,2) + int(b,2)
        return bin(c)[2:]

7.x 的平方根

题目描述:

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 x 是非负整数。

由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

示例 1:

输入: 4
输出: 2
示例 2:

输入: 8
输出: 2
说明: 8 的平方根是 2.82842..., 
     由于返回类型是整数,小数部分将被舍去。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sqrtx
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

  1. 本次我们使用二分查找法,通过观察我们可以发现,当整数大于3时,整数的平方根就小于等于该数的二分之一
  2. 定义left和right,left为0,right为x//2+1,x//2+1用于兼容0,1,2,3
  3. 使用while循环,当left不小于right时,跳出循环,定义变量mid为(left+right+1)//2,当mid的平方大于x时,right = mid - 1,否则,left等于mid
  4. 通过一次次的循环查找,最后得到的left等于right,且都为x的平方根

代码实现:

class Solution:
    def mySqrt(self, x: int) -> int:
        left = 0
        right = x//2 + 1
        while left < right:
            mid = (left + right + 1)//2
            sqrt = mid*mid
            if sqrt > x:
                right = mid - 1
            else:
                left = mid
        return right

8.统计参与通信的服务器(2020.1.8)

题目描述:

这里有一幅服务器分布图,服务器的位置标识在 m * n 的整数矩阵网格 grid 中,1 表示单元格上有服务器,0 表示没有。

如果两台服务器位于同一行或者同一列,我们就认为它们之间可以进行通信。

请你统计并返回能够与至少一台其他服务器进行通信的服务器的数量。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-servers-that-communicate
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

  1. 定义空列表count_m、count_n,分别求得每一行、每一列出现元素1的个数,并存放到count_m、count_n中
  2. 定义变量sum为0,变量列表,判断当前元素所在位置count_m或count_n是否大于1,如果大于1,再判断当前元素是否为1,如果都满足,则说明该位置的服务器是可通信服务器,sum加1
  3. 返回sum

代码实现:

class Solution:
    def countServers(self, grid: List[List[int]]) -> int:
        count_m = list()
        count_n = list()
        #判断每一行出现元素1的次数,并存放在count_m 
        for x in range(len(grid)):
            count_x = grid[x].count(1)
            count_m.append(count_x)
        #判断每一列出现元素1的次数,并存放在count_n
        for y in range(len(grid[0])):
            count_y = 0
            for x1 in range(len(grid)):
                if grid[x1][y] == 1:
                    count_y += 1
            count_n.append(count_y)
        sum = 0
        #判断每个元素是否可以通信,如果可以,sum加1
        for y in range(len(grid)):
            for x in range(len(grid[y])):
                if count_m[y] > 1 or count_n[x] > 1:
                    if grid[y][x] == 1:
                        sum += 1
        return sum

9.爬楼梯(2020.1.9)

题目描述:

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

示例 1:

输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1.  1 阶 + 1 阶
2.  2 阶
示例 2:

输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1.  1 阶 + 1 阶 + 1 阶
2.  1 阶 + 2 阶
3.  2 阶 + 1 阶

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/climbing-stairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

  1. 假设爬上第n阶楼梯有f(n)中方法,经过分析我们发现,f(n) = f(n-1) + f(n-2)
  2. 我们使用动态规划的思想,定义包含n+1个元素的列表dp,dp[n] = dp[n-1] + dp[n-2]
  3. 使用for循环获取列表dp各元素的值,最后返回我们要求解的dp[n]

代码实现:

class Solution:
    def climbStairs(self, n: int) -> int:
        dp = [0]*(n+1)
        dp[1] = 1
        if n < 2:
            return 1
        dp[2] = 2
        for i in range(3,n+1):
            dp[i] = dp[i-1] + dp[i-2]
        return dp[n]

10.合并两个有序数组(2020.01.10)

题目描述:

给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。

说明:

初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:

输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6],       n = 3

输出: [1,2,2,3,5,6]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

  1. 使用双指针解法,定义指针p1/p2都为0,定义变量num1_copy等于num1前m个元素
  2. 使用p1指向列表num1_copy,p2指向列表nums2,对比p1和p2所指元素的大小,将较小的赋值给nums1[p1+p2]
  3. 将nums1_copy,nums2剩余的元素添加到nums1中,最后将nums1前m+n个元素返回

代码实现:

class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        """
        Do not return anything, modify nums1 in-place instead.
        """
        p1 = 0
        p2 = 0
        nums1_copy = nums1[:m]

        while p1

 

你可能感兴趣的:(Python)