LeetCode 数组 容易 python

*********************************************
2018-05-22  May Tuesday the 21 week, the 142 day SZ
这个文档用python在Leetcode上来刷题,打算每天早上过来后先刷3道题,周末刷10道题。一个月140个题。
这个是中文版的
标注’问题‘的说明还有些问题,方便以后搜索查询
网页版使用说明:在问题前面画上对号的说明自己已经提交成功了
刚开始刷题很慢,每天只能刷3道题左右,因为很多题目网友的答案没有解说,自己只能用print去输出结果,去猜测网友的脑洞,最后才发现网友真的是太有才了。
后来多看几个网友的答案,自己再想想自己的答案,然后一道题就能够耗费一个上午。
*********************************************
########################
算法 容易
数组部分,
汉化版 leetcode,PYTHON题答案
######################
1 去除数组中重复数字,并且返回新数组
从排序数组中删除重复项
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

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

示例 1:
给定数组 nums = [1,1,2], 

函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 

你不需要考虑数组中超出新长度后面的元素。

示例 2:
给定 nums = [0,0,1,1,1,2,2,3,3,4],

函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。

你不需要考虑数组中超出新长度后面的元素。


#这段代码耗时非常短,主要是假设了列表是排好序的。当然也可以用函数先对无序列表排序
class Solution(object):
	def removeDuplication(self,old_list):
		i = 0
		while i < len(old_list)-1:
			if old_list[i] == old_list[i+1]:
				old_list.remove(old_list[i])
			else:
				i += 1
		return old_list



my_solution = Solution()
old_list = [1,1,2,2,3]
a = my_solution.removeDuplication(old_list)
print(a)



[1, 2, 3]
[Finished in 0.5s]


方法2 
class Solution(object):
  def removeDuplication(self,old_list):


      new_list = list(set(old_list)) #set函数可以去除列表中的重复元素,并且变成集合的形式,所以前面添加的list又把集合转化为列表形式输出
      return new_list


my_solution = Solution()
old_list = [1,1,2,2,3]
a = my_solution.removeDuplication(old_list)
print(a)


[1, 2, 3]
[Finished in 5.6s]
2
买卖股票的最佳时机 II

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:
输入: [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。


示例 2:
输入: [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
     因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。


示例 3:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。



#交易多次股票求最大利润的代码
class Solution(object):
    def maxProfit(prices):
        """
        :type prices: List[int]
        :rtype: int
        """
       
        if prices is None or len(prices) ==0:
        	return 0
        begin_value = prices[0]
        result = 0
        for i in prices:
        	if i > begin_value:
        		result= result + i - begin_value  #多次买入求累计利润
        		begin_value = i 				#重新买入
        	else:
        		begin_value = min(i, begin_value)
        return result

prices = [7,1,5,3,6,4]
a = Solution.maxProfit(prices)
print(a)

3  通过 

2018-05-23  May Wednesday the 21 week, the 143 day SZ
旋转数组
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。

示例 1:
输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]


示例 2:
输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
解释: 
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]

说明:
•尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
•要求使用空间复杂度为 O(1) 的原地算法
#python 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。

class Solution(object):
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        len_nums = len(nums)
        nums[:] = nums[len_nums-k:] + nums[:len_nums-k]




test_nums1 = [-1, -100, 3, 99]
test_nums2 = [1, 2, 3, 4, 5, 6, 7]

my_solution = Solution()
my_solution.rotate(test_nums1, 2)
my_solution.rotate(test_nums2, 3)
print(test_nums1)
print(test_nums2)

 
4  通过
2018-05-23  May Wednesday the 21 week, the 143 day SZ
存在重复
给定一个整数数组,判断是否存在重复元素。

如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。

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

示例 2:
输入: [1,2,3,4]
输出: false

示例 3:
输入: [1,1,1,3,3,4,3,2,4,2]
输出: true
'''
思路:
通过set函数删除重复数字,然后通过判断新旧数组长度是否相同
'''
class Solution(object):
    def containsDuplicate(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        if len(set(nums)) == len(nums): #set函数删除重复数字,并且把数组变成集合形式
        	return False
        else:
        	return True

test_nums2 = [1, 2, 3, 3, 5, 6, 7]
my_solution = Solution()
a = my_solution.containsDuplicate(test_nums2)

print(a)


5 通过
只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:
输入: [2,2,1]
输出: 1


示例 2:
输入: [4,1,2,1,2]
输出: 4
方法1:异或法
#^异或代表,两个数不同时候为1.
class Solution(object):
	def singleNumber(self, nums):
		temp = 0
		for i in nums:
			temp = temp ^ i #任何数和0异或都是本身,两个相同的数字异或为0
		return temp

my_solution = Solution()
nums = [4,1,2,1,2]
a = my_solution.singleNumber(nums) 
print(a)

6  两个数组的交集 问题
给定两个数组,写一个方法来计算它们的交集。

例如:
给定 nums1 = [1, 2, 2, 1], nums2 = [2, 2], 返回 [2, 2].

注意:
•   输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
•   我们可以不考虑输出结果的顺序。

跟进:
•如果给定的数组已经排好序呢?你将如何优化你的算法?
•如果 nums1 的大小比 nums2 小很多,哪种方法更优?
•如果nums2的元素存储在磁盘上,内存是有限的,你不能一次加载所有的元素到内存中,你该怎么办?


'''
解法1
思路:暴力法,循环比较数组2中是否有某个值和数组1中相同
'''
class Solution(object):
    def intersect(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: List[int]
        """
        res = []
        for num1 in nums1:
            #index = -1 
            for j in range(0, len(nums2)):
                if nums2[j] == num1:
                    index = j
                    break
            if index != -1:
                res.append(num1)
                del nums2[index]
                   

        return res
my_solution = Solution()
nums1 = [1,2,2]
nums2 = [3,2,2,1]
a = my_solution.intersect(nums1, nums2)
print(a)


'''
解法2通过
思路:先给数组排序,然后用两个指针依次比较,如果相等则指针都加一,如果....
'''
class Solution(object):
    def intersect(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: List[int]
        """
        res = []
        nums1.sort()
        nums2.sort()
        i = j = 0
        while i < len(nums1) and j < len(nums2):
            if nums1[i] == nums2[j]:
                res.append(nums1[i])
                i+=1
                j+=1
            elif nums1[i] < nums2[j]:
                i += 1
            else:
                j +=1
                   

        return res
my_solution = Solution()
nums1 = [1,2,2]
nums2 = [3,2,4,1]
a = my_solution.intersect(nums1, nums2)
print(a)
'''
        for i in range(len(nums1)):
            for j in range(len(nums2)):

                '''

7 加一
给定一个非负整数组成的非空数组,在该数的基础上加一,返回一个新的数组。

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

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

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


示例 2:
输入: [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321。
#2018-05-30  May Wednesday the 22 week, the 150 day SZ
'''
解法1 思路:
把列表看成整数,然后加一,输出。第一步:把列表转化为整数,第二部整数加一然后转化为列表输出
把列表看成十进制数字,个位乘以1,十位乘以10,以此类推。
把列表反转,然后进行十进制转化,enumerate函数把列表组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
返回的那个数字加一就行了,然后把返回的数字列表化。map() 会根据提供的函数对指定序列做映射。
'''
class Solution:
    def plusOne(self, digits):
        dint = 0
        for i,j in enumerate(digits[::-1]):         #digits[::-1]可以把列表里面元素反转,digits只是按照原样输出
            dint += j*10**i                             
            #print(i,j,dint)

        return list(map(int,str(dint+1))) 
        #map()函数Python 2.x 返回列表。Python 3.x 返回迭代器。int() 函数用于将一个字符串或数字转换为整型。str()函数返回一个对象的string格式。


my_solution = Solution()

nums = [4,1,2,3]
print(list(enumerate(nums[::-1])))
a = my_solution.plusOne(nums) 
print(a)

[4, 1, 2, 4]
[Finished in 0.5s]
在LeetCode里面算是最慢的算法了。但就是简洁,简单到让人尖叫


#2018-05-30  May Wednesday the 22 week, the 150 day SZ

'''
解法2思路:
利用递归法,用if判断末尾是否数字9,如果是,那就给删除9的数组继续递归,比上一个算法快些
'''
class Solution:
    def plusOne(self, digits):
        if len(digits) == 0: #判断数组长度,为空,返回1
            digits = [1]
        elif digits[-1] == 9: #末尾为9
            digits = self.plusOne(digits[:-1]) #递归调用函数,如果倒数第二位也是9,那就继续递归
            digits.extend([0]) #数组末尾添加0
        else:                                  #如果末尾不是9,末尾加一
            digits[-1] += 1
        return digits


my_solution = Solution()

nums = [4,1,2,3]
a = my_solution.plusOne(nums) 
print(a)
8 移动0 
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]

说明:
1.必须在原数组上操作,不能拷贝额外的数组。
2.尽量减少操作次数。



'''
解法1没通过哈,思路:
for循环把数字0和其他东西分开放在另外两个数组里面,然后把新建的两个数组相加。
leetcode给的错误信息,看了下,原来是人家要求只用一个数组解决问题。我总共使用了三个数组解决问题。
Line 63: SyntaxError: EOF while scanning triple-quoted string literal
'''
class Solution:
    def moveZeroes(self, digits):
        digits1 = []
        digits2 = []
        for i in digits:
            if i ==0:
                digits1.extend([0])
            else:
                digits2.extend([i])
        return digits2 + digits1


my_solution = Solution()

nums = [0,1,0,3,12]
a = my_solution.moveZeroes(nums) 
print(a)

[1, 3, 12, 0, 0]
[Finished in 0.6s]

#2018-05-30  May Wednesday the 22 week, the 150 day SZ

'''
解法2没通过哈,思路:
for循环,碰到0,删除,最后添加一个0.循环一遍就搞定了
leetcode反馈如下,反正不让我通过
Do not return anything, modify nums in-place instead.

'''
class Solution:
    def moveZeroes(self, digits):
        if len(digits) == 0:
            return digits
        else:

            for i in digits:
                if i ==0:
                    digits.remove(i)

                    digits.append(0)


        return digits


my_solution = Solution()

nums = [0,1,0,3,12]
a = my_solution.moveZeroes(nums) 
print(a)



[1, 3, 12, 0, 0]
[Finished in 5.2s]
leetcode反馈如下,反正不让我通过
Do not return anything, modify nums in-place instead.

我目前还没有发现问题在哪里
#2018-05-30  May Wednesday the 22 week, the 150 day SZ

'''
解法3通过哈,思路:
#if保证找到非零元素,如果是0,就不会执行if 下面的语句。index确定零元素的起始位置。
'''
class Solution(object):
    def moveZeroes(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        index = 0
        for n in nums:
            if n:                                   #保证找到非零元素,如果是0,就不会执行if 下面的语句
                nums[index] = n
                index += 1
        for i in range(index, len(nums)):
            nums[i] = 0
        #return nums            #题目要求不要返回值,所以这行删除,所有行为都是在原数组上操作。


my_solution = Solution()

nums = [0,1,0,3,12]
a = my_solution.moveZeroes(nums) 
print(a)






2018-05-23  May Wednesday the 21 week, the 143 day SZ
9 两数之和
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。

你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

示例:
给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

'''
解法1通过,思路:
for循环做两个纸针,第一个指针保持不动,一次增大第二个指针。然后再增大第一个指针。这样保证所有数字都充分利用了
'''
class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        len_nums = len(nums)
        for i in range(len_nums):
            for j in range(i +1, len_nums):
                if nums[i]  == target - nums[j]:
                    return i, j
                    break               #break保证i只能被使用一次。要不然同一个i会有几个j对应。
                else:
                    continue
my_solution = Solution()

nums = [0,1,0,3,12]
a = my_solution.twoSum(nums,15) 
print(a)



'''
解法2没有通过,思路:
用一个for循环查找target - nums[i]是否存在nums列表中
'''
class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        len_nums = len(nums)
        for i in range(len_nums):
            a = target - nums[i]
            if a in nums:
                j = nums.index(a)           #index函数求匹配元素的第一个索引,如果列表有重复元素就完蛋了
                return i,j

                break               #break保证i只能被使用一次。要不然同一个i会有几个j对应。
            else:
                continue
my_solution = Solution()

nums = [0,1,0,3,12]
a = my_solution.twoSum(nums,15) 
print(a)



10  有效的数独
判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
1.数字 1-9 在每一行只能出现一次。
2.数字 1-9 在每一列只能出现一次。
3.数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。



上图是一个部分填充的有效的数独。

数独部分空格内已填入了数字,空白格用 '.' 表示。

示例 1:
输入:
[
  ["5","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]
输出: true


示例 2:
输入:
[
  ["8","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]
输出: false
解释: 除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。
     但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

说明:
•一个有效的数独(部分已被填充)不一定是可解的。
•只需要根据以上规则,验证已经填入的数字是否有效即可。
•给定数独序列只包含数字 1-9 和字符 '.' 。
•给定数独永远是 9x9 形式的。

'''
数独成立条件:
一个9行9列的棋盘,每行每列和每一个3*3的小方格都不能有重复的数字,并且数字只能是0-9,逐一判断这些规则是否满足即可
解法1,思路:
依照规则,依次次判断每行元素是否重复,每列元素是否重复,每个小的九宫格是否重复。
判断数列是否有重复数字的方法就是给同一个数字赋相同的值,如果成立,就说明碰到重复的数字了
用数组里面的值给对应的空列表赋值,同样的数字只能给对应的地方赋值,如果发现坑已经被占了,那肯定有人来过。这个想法不错
'''
class Solution:
    # @param {character[][]} board
    # @return {boolean}
    def isValidSudoku(self, board):
        if len(board)!=9 or len(board[0])!=9:return False #确认是个9行9列的数组
        for i in range(9): #0到8总共9次循环,确定行没有重复数字
            map=[0 for k in range(10)] #得到一个有十个0的列表[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
            for j in range(9): 
                if board[i][j]=='.':continue #放过空格
                if board[i][j]<'0' or board[i][j]>'9':return False #数字在0到9之外就不是数独了
                num = ord(board[i][j])-ord('0')    #得到board[i][j]的数值,ord函数可以得到对应字符的数字形式
                if map[num]==1:return False
                #print("map[num] is:",map[num])
                map[num]=1
                #print("map[num] is:",map[num])

        #0到8总共9次循环,确定列没有重复数字
        for j in range(9):
            map=[0 for k in range(10)]
            for i in range(9):
                if board[i][j]=='.':continue
                num = ord(board[i][j])-ord('0')
                #print("num is:",num)
                if map[num]==1:return False #判断是否有重复的数字:第一次map[num]被赋值1,如果再次碰到同一个num,map[num]等于1成立,然后返回False,程序退出循环
                #print("map[num] is:",map[num])

                map[num]=1
                #print("map[num] is:",map[num])

        #确定小宫格的情况
        for i in range(0,9,3):
            for j in range(0,9,3):
                map=[0 for k in range(10)]
                for k in range(i,i+3):
                    for l in range(j,j+3):
                        if board[k][l]=='.':continue
                        num = ord(board[k][l])-ord('0')
                        if map[num]==1:return False
                        map[num]=1
        return True

my_solution = Solution()

board1 =  [
  ["8","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]
board2 = [
  ["5","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]

a = my_solution.isValidSudoku(board1) 
print(a)

b = my_solution.isValidSudoku(board2) 
print(b)
2018-05-23  May Wednesday the 21 week, the 143 day SZ
11 旋转图像
给定一个 n × n 的二维矩阵表示一个图像。

将图像顺时针旋转 90 度。

说明:

你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。

示例 1:
给定 matrix = 
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],

原地旋转输入矩阵,使其变为:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]


示例 2:
给定 matrix =
[
  [ 5, 1, 9,11],
  [ 2, 4, 8,10],
  [13, 3, 6, 7],
  [15,14,12,16]
], 

原地旋转输入矩阵,使其变为:
[
  [15,13, 2, 5],
  [14, 3, 4, 1],
  [12, 6, 8, 9],
  [16, 7,10,11]
]

'''
方法1直接旋转,太抽象,普通人想不到这里,真的很巧妙。

'''

class Solution(object):
    def rotate(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: void Do not return anything, modify matrix in-place instead.
        """
        res = []
        
        while matrix[0]:
            tmp = []
            #print("matrix is:",matrix)
            for循环进行依次,就弹出旧数组的一列,并且放到新数组中组成一行
            for row in matrix:                                                
                #print("row is:",row)
                tmp.insert(0,row.pop(0))   #list.insert(position,value)。tmp里面放的是新图片的行
                #print("tmp is:",tmp)  
            #print("temp is",tmp)           
            res.append(tmp)         #把所有的tmp行放到res中,res就是翻转后的新图像
            #print("res is:",res)
        #把res赋给旧图片
        for i in range(len(matrix)): #这里,必须对matrix中的每行都进行修改,才能对其重新赋值,不能直接:matrix=res
            matrix[i] = res[i]
            print("for :",matrix[i])
        
s = Solution()
matrix = [[1,2],[3,4]]
s.rotate(matrix)
print(matrix)

'''
方法2通过
思路:
先把矩阵按照对角线对换位置,然后新的矩阵按照行逆转,经过两步就是图片的九十度顺时针旋转了。
发散思维:如果图像逆时针旋转怎么办。
也是两步走,按照相反的对角线调换位置,然后把每行逆转就成功了

'''
class Solution(object):
    def rotate(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: void Do not return anything, modify matrix in-place instead.
        """
        size = len(matrix)
        for i in range(size):
            for j in range(i + 1,size):
                matrix[i][j],matrix[j][i] = matrix[j][i],matrix[i][j]
        for i in range(size):
            matrix[i].reverse()
        
s = Solution()
matrix = [[1,2],[3,4]]
s.rotate(matrix)
print(matrix)

*********************数组简单部分结束**************************************

猜你喜欢

转载自blog.csdn.net/btujack/article/details/80540401