python练习(三)

  • Friend Circles
    • 题目
    • 思路
    • 答案
      • 思考
      • 重写
  • Combination Sum IV
    • 思路
    • 解答
    • 答案
      • 思考
      • 重写
  • Reverse Pairs
    • 题目
    • 思路
    • 解答
    • 答案
    • 思考
      • 重写
  • Add Digits
    • 题目
    • 思路
    • 解答
      • 修改
    • 答案
    • 答案二
      • 解释
      • 代码
      • 思考
        • 网上的解释
  • Happy Number
    • 题目
    • 思路
    • 解答
    • 答案

https://leetcode.com
啊啊啊啊,我之前写的没存,全都没了,全都没了啊QAQ

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

Friend Circles

题目

There are N students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a direct friend of B, and B is a direct friend of C, then A is an indirect friend of C. And we defined a friend circle is a group of students who are direct or indirect friends.

Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] = 1, then the ith and jth students are direct friends with each other, otherwise not. And you have to output the total number of friend circles among all the students.

Example 1:
Input: 
[[1,1,0],
 [1,1,0],
 [0,0,1]]
Output: 2

Explanation:The 0th and 1st students are direct friends, so they are in a friend circle.
The 2nd student himself is in a friend circle. So return 2.

Example 2:
Input: 
[[1,1,0],
 [1,1,1],
 [0,1,1]]
Output: 1

Explanation:The 0th and 1st students are direct friends, the 1st and 2nd students are direct friends,
so the 0th and 2nd students are indirect friends. All of them are in the same friend circle, so return 1.

思路

我记得当时看到时候根本无从下手

答案

def findCircleNum(self, A):
    N = len(A)
    seen = set()
    def dfs(node):
        for nei, adj in enumerate(A[node]):
            if adj and nei not in seen:
                seen.add(nei)
                dfs(nei)

    ans = 0
    for i in xrange(N):
        if i not in seen:
            dfs(i)
            ans += 1
    return ans

思考

发现是由深度优先算法完成的,深度优先算法我也知道,但是没有想过如何跟实际相结合

重写

根据深度优先算法自己写的

class Solution(object):
    def findCircleNum(self, M):
        """
        :type M: List[List[int]]
        :rtype: int
        """
        l = set()
        s=0
        def dfs(i):
            for key, values in enumerate(M[i]):
                if key not in l and values == 1:
                    l.add(key)
                    dfs(key)    

        for key in xrange(len(M)):
            if key not in l:
                dfs(key)
                s +=1

        return s

Combination Sum IV

Given an integer array with all positive numbers and no duplicates, find the number of possible combinations that add up to a positive integer target.

Example:

nums = [1, 2, 3]
target = 4

The possible combination ways are:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)

Note that different sequences are counted as different combinations.

Therefore the output is 7.

思路

这个用递归做正好啊

解答

用递归在测试时超时了…

class Solution(object):
    def combinationSum4(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums.sort()    
        def dfs(n):
            i=0
            for x in nums:
                if x == n:
                    i +=1
                elif x < n:
                    i +=dfs(n-x)
                else:
                    break
            return i

        return dfs(target)

答案

class Solution(object):
    def combinationSum4(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums, combs = sorted(nums), [1] + [0] * (target)
        for i in range(target + 1):
            for num in nums:
                if num  > i: break
                if num == i: combs[i] += 1
                if num  < i: combs[i] += combs[i - num]
        return combs[target]

思考

这是把每一个数(dfs(n))都算出来,然后组合的啊

重写

class Solution(object):
    def combinationSum4(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums.sort()
        c=[0]*(target+1)
        for i in xrange(target+1):
            for x in nums:
                if x == i:
                    c[i] +=1
                elif x < i:
                    c[i] +=c[i-x]
                else:
                    break     
        return c[target]

Reverse Pairs

题目

Given an array nums, we call (i, j) an important reverse pair if i < j and nums[i] > 2*nums[j].

You need to return the number of important reverse pairs in the given array.

Example1:

Input: [1,3,2,3,1]
Output: 2
Example2:

Input: [2,4,3,5,1]
Output: 3

思路

看起来很简单吗,两遍遍历稳稳的做出来,不过估计会稳稳地超时吧

解答

两遍遍历的稳稳地超时了

答案

class Solution(object):
    def __init__(self):
        self.cnt = 0
    def reversePairs(self, nums):
        def msort(lst):
            # merge sort body
            L = len(lst)
            if L <= 1:                          # base case
                return lst
            else:                               # recursive case
                return merger(msort(lst[:int(L/2)]), msort(lst[int(L/2):]))
        def merger(left, right):
            # merger
            l, r = 0, 0                         # increase l and r iteratively
            while l < len(left) and r < len(right):
                if left[l] <= 2*right[r]:
                    l += 1
                else:
                    self.cnt += len(left)-l     # add here
                    r += 1
            return sorted(left+right)           # I can't avoid TLE without timsort...

        msort(nums)
        return self.cnt

思考

看起来这个东西有些面熟啊,这个好像使用了合并排序的思想?
本来漏看了merger函数的return,导致一直没想通
最后大致明白了

重写

这次重写的差不多,就不贴了
重写过程中出了几个问题
一个是第一个函数的return出现了失误,没有将函数递归使用使其分割成最小单元

我明明想先做做easy难度的,怎么给了个hard的???

Add Digits

题目

Given a non-negative integer num, repeatedly add all its digits until the result has only one digit.

For example:

Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it.

思路

不愧是easy难度的看起来就很简单,明显的递归

解答

class Solution(object):
    def addDigits(self, num):
        """
        :type num: int
        :rtype: int
        """
        def fff(num):
            l = str(num)
            s = 0
            for i in l:
                s +=int(i)
            if s<10:
                return s
            else:
                return fff(s)

        return fff(num)

修改

之后看到个列表生成式,那我的代码可一缩减成

class Solution(object):
    def addDigits(self, num):
        """
        :type num: int
        :rtype: int
        """
        def fff(num):
            s = sum([int(i) for i in str(num)])
            if s<10:
                return s
            else:
                return fff(s)  
        return fff(num)

答案

      class Solution(object):
      def addDigits(self, num):
        """
        :type num: int
        :rtype: int
        """
        while(num >= 10):
            temp = 0
            while(num > 0):
                temp += num % 10
                num /= 10
            num = temp
        return num

用循环来解决问题,我光想着递归了,而且我转类型转来转去的,确实不好。

答案二

解释

Digital Root
this method depends on the truth:

N=(a[0] * 1 + a[1] * 10 + ...a[n] * 10 ^n),and a[0]...a[n] are all between [0,9]

we set M = a[0] + a[1] + ..a[n]

and another truth is that:

1 % 9 = 1

10 % 9 = 1

100 % 9 = 1

so N % 9 = a[0] + a[1] + ..a[n]

means N % 9 = M

so N = M (% 9)

as 9 % 9 = 0,so we can make (n - 1) % 9 + 1 to help us solve the problem when n is 9.as N is 9, ( 9 - 1) % 9 + 1 = 9

代码

class Solution(object):
def addDigits(self, num):
    """
    :type num: int
    :rtype: int
    """
    if num == 0 : return 0
    else:return (num - 1) % 9 + 1

思考

这是利用数学相关的知识了吧
不过这个方法测试为什么比我的代码还慢……

网上的解释

假设输入的数字是一个5位数字num,则num的各位分别为a、b、c、d、e。

有如下关系:num = a * 10000 + b * 1000 + c * 100 + d * 10 + e

即:num = (a + b + c + d + e) + (a * 9999 + b * 999 + c * 99 + d * 9)

因为 a * 9999 + b * 999 + c * 99 + d * 9 一定可以被9整除,因此num模除9的结果与 a + b + c + d + e 模除9的结果是一样的。

对数字 a + b + c + d + e 反复执行同类操作,最后的结果就是一个 1-9 的数字加上一串数字,最左边的数字是 1-9 之间的,右侧的数字永远都是可以被9整除的。

可是如何保证二次的呢?
假设
num2=a+b+c+d+e=f*10+g
num3=f+g=….
实际上还是不断去掉n个9
好吧这样才懂

Happy Number

题目

Write an algorithm to determine if a number is "happy".

A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.

Example: 19 is a happy number

12+92=82
82+22=68
62+82=100
12+02+02=1

思路

这个不会也有规律和9相关吧,哦,算了一下,好像没有

解答

最初由于if判断顺序的问题,导致输入1都失败了
修改后测试输入2超时了,尴尬
想加print测试下,直接未响应了。
哦,循环不一定包括输入的数字,尴尬
终于通过了,测试结果还是挺快的

class Solution(object):
    def isHappy(self, n):
        """
        :type n: int
        :rtype: bool
        """
        l = [n]
        while True:
            temp = 0
            while(n > 0):
                temp += (n % 10) ** 2
                n /= 10

            n = temp
            if n == 1:
                return True
            elif n in l :
                return False
            else:
                l.append(n)

答案

def isHappy(self, n):
    mem = set()
    while n != 1:
        n = sum([int(i) ** 2 for i in str(n)])
        if n in mem:
            return False
        else:
            mem.add(n)
    else:
        return True

列表生成式,看起来厉害些

5题一组吧

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