python练习(五)

  • Can Place Flowers
    • 题目
    • 思路
    • 解答
    • 答案
  • Best Time to Buy and Sell Stock II
    • 题目
    • 思路
    • 解答
    • 答案
  • Base 7
    • 题目
    • 思路
    • 解答
    • 答案
  • Array Partition I
    • 题目
    • 思路
    • 解答
    • 答案
  • Find All Anagrams in a String
    • 题目
    • 思路
    • 解答
    • 答案
      • 重写

注意,答案只是代表是他人写的代码,正确,但不一定能通过测试(比如超时),列举出来只是它们拥有着独到之处,虽然大部分确实都比我的好

Can Place Flowers

题目

Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, flowers cannot be planted in adjacent plots - they would compete for water and both would die.

Given a flowerbed (represented as an array containing 0 and 1, where 0 means empty and 1 means not empty), and a number n, return if n new flowers can be planted in it without violating the no-adjacent-flowers rule.

思路

一次循环看起来就能解决的问题,应该会有快速算法吧

解答

class Solution(object):
    def canPlaceFlowers(self, flowerbed, n):
        """
        :type flowerbed: List[int]
        :type n: int
        :rtype: bool
        """
        f=0
        for i in range(len(flowerbed)-1):
            if flowerbed[i] == 0:
                if f == 0 and flowerbed[i+1] == 0:
                    n -=1
                    f =1
                else :
                    f=0
            else:
                f = 1
            if n <= 0:
                return True
        if flowerbed[-1] == 0 and f == 0:
            n -=1
        if n <= 0:
            return True
        else:
            return False

76%,估计也没有太大的优化余地了

答案

class Solution(object):
    def canPlaceFlowers(self, flowerbed, n):
        """
        :type flowerbed: List[int]
        :type n: int
        :rtype: bool
        """
        for i, x in enumerate(A):
            if (not x and (i == 0 or A[i-1] == 0) 
                and (i == len(A)-1 or A[i+1] == 0)):
                N -= 1
                A[i] = 1
    return N <= 0

f****k,我清楚的记得不是在这个位置保存,下边的内容又双叒叕丢了

超长的判断我不喜欢
我不应该用变量f的
return N <= 0 哦?倒是可以理解,从未想过还能这样用

Best Time to Buy and Sell Stock II

题目

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

思路

看起来有些困难,因为在抛售股票后下一个购买点,哦,只要把之前的峰值累加就好了吧
不对,比如[3,5,4,8]这种队列,还是无法确认购买点,唔,只要当前价格比上一个卖出价格小就好?

解答

class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        if len(prices) == 0:
            return 0
        psum = 0
        minprice = prices[0]
        maxprice = 0
        for price in prices:
            if price < maxprice:
                psum += maxprice - minprice
                minprice = maxprice = price
            elif price > maxprice:
                maxprice = price
        if prices[-1] > minprice:
            psum += prices[-1] - minprice
        return psum      

本来不需要加上非空判断的,但是由于测试时发现没有判断结尾,导致一些问题,所以添加了结尾检测,但由于结尾检测的存在,导致空表进来就出错,所以又要加上空表检测

答案

class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        max_prof = 0
        for i in range(len(prices)-1):
            if prices[i+1] > prices[i]:
                max_prof += prices[i+1] - prices[i]
        return max_prof

。。。卧槽我为什么想得那么复杂?宛如(就是)一个zz

Base 7

题目

Given an integer, return its base 7 string representation.

Example 1:
Input: 100
Output: “202”
Example 2:
Input: -7
Output: “-10”
Note: The input will be in range of [-1e7, 1e7].

思路

10进制转7进制。

解答

直接”.join(l[::-1])会报错TypeError: sequence item 0: expected string, int found,由于l内不全是str
可以用一下的操作处理”.join(map(str,l[::-1]))
忘了将return 0 处理为return‘0’了

class Solution(object):
    def convertToBase7(self, num):
        """
        :type num: int
        :rtype: str
        """
        if num > 0:
            f = 0
        elif num == 0:
            return '0'
        else :
            num = -num
            f = 1
        l=[]
        while num > 0:
            l.append(num%7)
            num = num/7
        return ('-' if f else '') + ''.join(map(str,l[::-1]))            

答案

class Solution(object):
    def convertToBase7(self, num):
        """
        :type num: int
        :rtype: str
        """
        if num<0:
            return "-"+self.convertToBase7(-num)

        if num<7:
            return str(num)

        return self.convertToBase7(num//7)+str(num%7)

递归的方式,很骚气,厉害了

def convertTo7(self, num):
    if num == 0: return '0'
    n, res = abs(num), ''
    while n:
      res = str(n % 7) + res
      n //= 7
    return res if num > 0 else '-' + res

直接使用字符串而不是使用表进行操作。看起来很棒

Array Partition I

题目

Given an array of 2n integers, your task is to group these integers into n pairs of integer, say (a1, b1), (a2, b2), …, (an, bn) which makes sum of min(ai, bi) for all i from 1 to n as large as possible.

Example 1:
Input: [1,4,3,2]

Output: 4
Explanation: n is 2, and the maximum sum of pairs is 4 = min(1, 2) + min(3, 4).

思路

理解了半天才大概弄懂,分成不同的一对一对的,求最大对数?
试了下,不是,连题目都看不懂做个毛线啊
搜了搜
对于每一对,我们计算min(a,b),并对所有最小值相加,我们想要最大的和。
原来是这样
也就是说去掉最大值,获取当前最大值,再去掉最大值,再获取当前最大值,如此重复即可
也就是对list排序后取1,3,5,7…位的就行了

解答

class Solution(object):
    def arrayPairSum(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        return sum(sorted(nums)[::2])

原来我也可以写出来一行的(只是因为题目太简单了吧)
只能说python功能真强

答案

和我的一样,没有更好的了哈哈

Find All Anagrams in a String

题目

Given a string s and a non-empty string p, find all the start indices of p's anagrams in s.

Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.

The order of output does not matter.

Example 1:

Input:
s: "cbaebabacd" p: "abc"

Output:
[0, 6]

Explanation:
The substring with start index = 0 is "cba", which is an anagram of "abc".
The substring with start index = 6 is "bac", which is an anagram of "abc".
Example 2:

Input:
s: "abab" p: "ab"

Output:
[0, 1, 2]

Explanation:
The substring with start index = 0 is "ab", which is an anagram of "ab".
The substring with start index = 1 is "ba", which is an anagram of "ab".
The substring with start index = 2 is "ab", which is an anagram of "ab".

思路

题目确实好懂,怎么做呢,而且提供的p长度还可以不小
不过python有in嘛

解答

class Solution(object):
    def findAnagrams(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: List[int]
        """
        p = sorted(p)
        l=[]
        for i in range(len(s)-len(p)+1):
            if sorted(''.join(s[i:i+len(p)])) == p:
                l.append(i)
        return l

本来还对自己这个想法而沾沾自喜,结果测试的时候超时了
看起来给了1万个a
这种输入似乎使用滚轮胎的方式好些,可是滚轮胎可不好写

各种错误,比如位置错误,重复错误

class Solution(object):
    def findAnagrams(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: List[int]
        """
        p = sorted(p)
        l=[]
        x=y=-1
        pl =len(p)
        for i in range(len(s)):
            if i < x:      
                continue
            elif i == x:
                if s[i] == s[x-pl]:
                    if x-pl+1 not in l:
                        l.append(x-pl+1)
                    x=i+1
                    y=x
                elif s[i] in p:
                    y=i+1
                elif i > len(s)-len(p):
                    break
            if sorted(''.join(s[i:i+pl])) == p :
                if i not in l:
                    l.append(i)
                if x < i:
                    x=i+pl
            if i == y:
                if sorted(''.join(s[i-pl+1:i+1])) == p:
                    if i-pl+1 not in l:
                        l.append(i-pl+1)
                    x=i+1
        return sorted(l)

改了半天,又双叒叕超时了

想不出来了,

答案

def findAnagrams(self, s, p):
    """
    :type s: str
    :type p: str
    :rtype: List[int]
    """
    d = defaultdict(int)
    ns, np = len(s), len(p)
    ans = []

    for c in p: d[c] -= 1

    for i in xrange(ns):
        if i < np:
            d[s[i]] += 1
            if not d[s[i]]: del d[s[i]]

        else:
            if not d: ans.append(i-np)

            d[s[i-np]] -= 1
            if not d[s[i-np]] : del d[s[i-np]]

            d[s[i]] += 1
            if not d[s[i]]: del d[s[i]]
    if not d: ans.append(i-np+1)

    return ans

defaultdict(int)生成一个字典,默认初始值为括号内的量。
我还没怎么用过字典,对于字典…
字典居然可以直接进行if判断
先生成一个字典d,其中key值为p内的各个字符,value值由出现次数决定,为对应负数。
然后将字符串s里的值一点一点填进去,当对应value值为0 时,删除对应key。当填够 len(p)的时候,判断d是否为空(如果以填入的值与p相同,d应为空),如果为空,则将对应i值填到答案表中。
然后该窗口开始滑动(即我说的滚轮胎……),去掉头部的值,加入最后的值(队列?),然后反复比较,移动。

   from collections import Counter

    def findAnagrams(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: List[int]
        """
        res = []
        pCounter = Counter(p)
        sCounter = Counter(s[:len(p)-1])
        for i in range(len(p)-1,len(s)):
            sCounter[s[i]] += 1   # include a new char in the window
            if sCounter == pCounter:    # This step is O(1), since there are at most 26 English letters 
                res.append(i-len(p)+1)   # append the starting index
            sCounter[s[i-len(p)+1]] -= 1   # decrease the count of oldest char in the window
            if sCounter[s[i-len(p)+1]] == 0:
                del sCounter[s[i-len(p)+1]]   # remove the count if it is 0
        return res

使用了Counter(p),类似于上一个方法的d,不过感觉不如第一个巧妙

重写

唔,用这个方法反而不好复现我之前的逻辑了,而且也没必要了
前面还要import一句话…

from collections import defaultdict
class Solution(object):
    def findAnagrams(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: List[int]
        """
        d = defaultdict(int)
        for i in p: 
            d[i] -= 1
        l=[]
        pl =len(p)
        for i in range(len(s)):
            if i < pl:
                d[s[i]] += 1
                if not d[s[i]]:
                    del d[s[i]]
            else:
                if not d:
                    l.append(i)
                d[s[i]] += 1
                if not d[s[i]]:
                    del d[s[i]]
                d[s[i-pl]] -= 1
                if not d[s[i-pl]]:
                    del d[s[i-pl]]
        if not d:
            l.append(len(s)-pl)
        return l

你可能感兴趣的:(学习之旅)