python练习(六)

来源:互联网 发布:联通申请开通80端口 编辑:程序博客网 时间:2024/04/20 22:21

  • House Robber
    • 题目
    • 思路
    • 解答
    • 答案
  • Find the Difference
    • 题目
    • 思路
    • 解答
    • 答案
  • Island Perimeter
    • 题目
    • 思路
    • 解答
    • 答案
  • Longest Common Prefix
    • 题目
    • 思路
    • 解答
    • 答案
  • Guess Number Higher or Lower
    • 题目
    • 思路
    • 解答
    • 答案

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

House Robber

题目

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

思路

和花坛的不一样,有种牵一发而动全身的感觉
获取最大值,获取二大值?万一二大和三打挨着最大呢。
无从下手。
类似那什么的 思想?逐步扩大,先求前两个的最大,再求前三个的,再前四

解答

class Solution(object):    def rob(self, nums):        """        :type nums: List[int]        :rtype: int        """        if len(nums) == 0 :return 0        ln = len(nums)        l = [0] + [nums[0]] + [0]*ln        for i in range(2,ln+1):            l[i] = max (l[i-1],l[i-2]+nums[i-1])        return l[ln]

0.58%。。。。再提交一遍就30%,还好

答案

class Solution:    def rob(self, nums):        last, now = 0, 0        for i in nums: last, now = now, max(last + i, now)        return now

原来只需要两个变量就行了。

Find the Difference

题目

Given two strings s and t which consist of only lowercase letters.

String t is generated by random shuffling string s and then add one more letter at a random position.

Find the letter that was added in t.

Example:

Input:
s = “abcd”
t = “abcde”

Output:
e

Explanation:
‘e’ is the letter that was added.

思路

这个用python写,有点太简单了?判断用的in,==都太强势了

解答

        return ''.join([i for i in t if i not in s])

本来想着一行搞定,结果出来个’a’,’aa’。。。还带这样玩的
难不成要用字典的方法了?我还想挣扎下

老老实实用字典吧

from collections import defaultdictclass Solution(object):    def findTheDifference(self, s, t):        """        :type s: str        :type t: str        :rtype: str        """        d = defaultdict(int)        for i in s:             d[i] -= 1        for i in range(len(t)):            d[t[i]] += 1            if not d[t[i]]:                del d[t[i]]        return ''.join([i for i in d.keys()])

答案

这个答案思路非常有趣

class Solution(object):    def findTheDifference(self, s, t):        return chr(reduce(operator.xor, map(ord, s + t)))

…chr我会,reduce我懂,xor我认识,map我会,ord我会,怎么摆一块我就有点懵呢?
先将s和t续在一起,然后用map把字符全变成ASCII码
然后全都异或???
等等,卧槽?卧槽?卧槽? 这也可以?
有两个相同的一异或全归零了,剩下的那个孤零零就是多出来的
厉害了

class Solution(object):    def findTheDifference(self, s, t):        return list((collections.Counter(t) - collections.Counter(s)))[0]

哦,应该不用字典直接用Counter()的,能短这么多
看了一会才看懂为什么会是个字符格式的,我又zz了,一个字符用什么”.join(),直接取出来不就好了

class Solution(object):    def findTheDifference(self, s, t):        s, t = sorted(s), sorted(t)        return t[-1] if s == t[:-1] else [x[1] for x in zip(s, t) if x[0] != x[1]][0]

我挣扎的时候怎么就忘了排序这事呢。
这句return也不简单呀
本来还在思考zip后,多出来的那一截不就没了,仔细想想好像没了就没了

Island Perimeter

题目

You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells). The island doesn’t have “lakes” (water inside that isn’t connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don’t exceed 100. Determine the perimeter of the island.

思路

深度优先算法?
像那个朋友圈一样?
好像可以做
可是朋友圈怎么做的来着
又好像不需要dfs,毕竟只要判断四个边而已
这样就要两重循环了啊

解答

还是写了两重循环,唉

class Solution(object):    def islandPerimeter(self, grid):        """        :type grid: List[List[int]]        :rtype: int        """        sum = 0         for n in range(len(grid)):            for i,v in enumerate(grid[n]):                if v:                    #上                    if n==0 or not grid[n-1][i]:                        sum += 1                    #下                    if n==len(grid)-1 or not grid[n+1][i]:                        sum += 1                    #左                    if i==0 or not grid[n][i-1]:                        sum += 1                    #右                    if i==len(grid[n])-1 or not grid[n][i+1]:                        sum +=1        return sum

61%,那大家都应该是这么做的喽

答案

def islandPerimeter(self, grid):    return sum(sum(map(operator.ne, [0] + row, row + [0]))               for row in grid + map(list, zip(*grid)))

令人窒息的操作,我搜都不知道怎么去搜。。。
反正看完了翻译也不是很好懂
不转置的和转置后的连接在一起,比较[0] + row, row + [0],好像也是异或?10,01得1,卧槽?
然后求和,循环,求和,真是骚气的操作。。。
厉害了
以下是翻译版

class Solution(object):    def islandPerimeter(self, grid):        grid_ext = ['0' + ''.join(str(x) for x in row) + '0' for row in grid]        grid_trans = list(map(list, zip(*grid)))        grid_ext += [ '0' + ''.join(str(x) for x in row) + '0' for row in grid_trans ]                        return sum(row.count('01') + row.count('10') for row in grid_ext)

有些理解了这个代码,虽然不太清楚为什么grid_trans就是转置了
(准确说zip(*grid)就已经转置了)

class Solution(object):    def islandPerimeter(self, grid):        """        :type grid: List[List[int]]        :rtype: int        """        count = 0        repeat = 0        for i in range(len(grid)):            for j in range(len(grid[0])):                if grid[i][j] == 1:                    count += 1                    if i != 0 and grid[i - 1][j] == 1:                        repeat += 1                    if j != 0 and grid[i][j - 1] == 1:                        repeat += 1        return count * 4 - repeat * 2 

这是统计块数及邻边的方法

Longest Common Prefix

题目

Write a function to find the longest common prefix string amongst an array of strings.

思路

好像要循环好久啊

解答

这网站不认两个单引号啊

class Solution(object):    def longestCommonPrefix(self, strs):        """        :type strs: List[str]        :rtype: str        """        if len(strs) == 0 : return ''        l = len(strs[0])        for i in strs:            l = min(len(i),l)        if not l: return ''        ns =''        s = strs[0][0]        x=0        while True:            for i in range(len(strs)):                if s != strs[i][:x+1]:                    return ns                if x == l-1 and i == len(strs)-1:                    return s            x += 1            ns = s            s = s + strs[0][x]

答案

class Solution(object):    def longestCommonPrefix(self, strs):        """        :type strs: List[str]; rtype: str        """        sz, ret = zip(*strs), ""        # looping corrected based on @StefanPochmann's comment below        for c in sz:            if len(set(c)) > 1: break            ret += c[0]        return ret

非常棒,zip,set啊

import osclass Solution:    # @param {string[]} strs    # @return {string}    def longestCommonPrefix(self, strs):        return os.path.commonprefix(strs)

咳咳咳,过分了昂

 def longestCommonPrefix(self, strs):        """        :type strs: List[str]        :rtype: str        """        if not strs:            return ""        shortest = min(strs,key=len)        for i, ch in enumerate(shortest):            for other in strs:                if other[i] != ch:                    return shortest[:i]        return shortest 

唉。。。
这个min的用法

Guess Number Higher or Lower

题目

We are playing the Guess Game. The game is as follows:

I pick a number from 1 to n. You have to guess which number I picked.

Every time you guess wrong, I’ll tell you whether the number is higher or lower.

You call a pre-defined API guess(int num) which returns 3 possible results (-1, 1, or 0):

-1 : My number is lower
1 : My number is higher
0 : Congrats! You got it!
Example:
n = 10, I pick 6.

Return 6.

思路

我是看了半天才看懂是个啥问题
2分法吧

解答

class Solution(object):    def guessNumber(self, n):        """        :type n: int        :rtype: int        """        l, r = 1, n        while l + 1 < r:            m =  (r + l) / 2            i = guess(m)            if i == -1:                r = m            elif i == 1:                l = m            else:                return m        if guess(l) == 0:            return l        if guess(r) == 0:            return r

答案

差不多
tips:
在进行猜测时,m = l + (r - l) / 2,我将其化简为m = (r + l) / 2,
这在python上是没有任何问题的,但在c++或其它语言(具体是哪些其它我就不清楚了)中,可能会由于r+l导致溢出(太大了)

这次感受到和python有关系了,无论是reduce,map,还是zip等等

原创粉丝点击