zoukankan      html  css  js  c++  java
  • LeetCode基本记录【4】// BASIC NOTES AND CODES OF LEETCODE [ 4 ]

    LeetCode基本记录【4】

    60. Permutation Sequence

    The set [1,2,3,…,n] contains a total of n! unique permutations.

    By listing and labeling all of the permutations in order,
    We get the following sequence (ie, for n = 3):

    "123"
    "132"
    "213"
    "231"
    "312"
    "321"
    

    Given n and k, return the kth permutation sequence.

    Note: Given n will be between 1 and 9 inclusive.

    # 观察string的字典序排列,首位数字的排列是:按照(n-1)!为一组,从小到大排列,所以对k做一次divmod,商i表示第i小的数,余数给下一位当做k使用
    # 每增加一位,就把这一位remove,这样保证之后的没有重复,第i小的数也是在remove之后的list中取值。
    # 注意计算过程中,k作为标识位置的下标应该先减一。
    class Solution(object):
        def getPermutation(self, n, k):
            """
            :type n: int
            :type k: int
            :rtype: str
            """
            ret = ''
            k = k - 1
            nums = range(1, n+1)
            while n > 0 :
                n -= 1
                i, k = divmod(k, self.factorial(n))
                ret += str(nums[i])
                nums.remove(nums[i])
            return ret
    
        def factorial(self, x):
            if not x or x == 1:
                return 1
            else:
                return reduce(lambda x,y : x * y, range(1,x+1))

    61. Rotate List

    Given a list, rotate the list to the right by k places, where k is non-negative.

    Example:

    Given 1->2->3->4->5->NULL and k = 2,

    return 4->5->1->2->3->NULL.

    # 题目较为简单,和删除linked list的倒数第k个元素有点相似
    # 但是考虑到特殊情况,比如rotate的次数大于链表的长度时,如果会有很多这种或者很大的rotate次数,那么应该考虑先查出链表长度再divmod,
    # 开始时以为这样的情况较少,于是直接把pt1做成了一个循环链表的指针,最后发现超出内存了。。于是用了先查出length再取余数的方法。
    # Definition for singly-linked list.
    # class ListNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution(object):
        def rotateRight(self, head, k):
            """
            :type head: ListNode
            :type k: int
            :rtype: ListNode
            """
            if not head : return None
            if not k : return head
            dummy = ListNode(0)
            dummy.next = head
            pt, pt1, pt2 = dummy.next, dummy.next, dummy.next
            le = 0
            while pt != None:
                le += 1
                pt = pt.next
            for i in range(k % le):
                pt1 = pt1.next
    #            if pt1 == None : 
    #                pt1 = dummy.next
            while pt1.next != None:
                pt1 = pt1.next
                pt2 = pt2.next
            pt1.next = dummy.next
            dummy.next = pt2.next
            pt2.next = None
            return dummy.next      

    62. Unique Paths

    A robot is located at the top-left corner of a m x n grid (marked ‘Start’ in the diagram below).

    The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked ‘Finish’ in the diagram below).

    How many possible unique paths are there?

    Above is a 3 x 7 grid. How many possible unique paths are there?

    Note: m and n will be at most 100.

    robot_maze.png

    # 直接用递归做会TLE,因为递归过程中所有的结果都是从头(0,0)点开始算出来的,因此有大量的重复计算。所以考虑用空间对换时间,
    # 也就是用动态规划,将每一步骤的结果记下来,然后按照递归的方法计算。
    # 对于这类矩阵中的路径问题,有记忆的DP是一种常规的方法。
    class Solution(object):
        def uniquePaths(self, m, n):
            """
            :type m: int
            :type n: int
            :rtype: int
            """
            mat = [[1] * n] * m
            for i in range(1, m):
                for j in range(1, n):
                    mat[i][j] = mat[i-1][j] + mat[i][j-1]
            return mat[-1][-1]

    63. Unique Paths II

    Follow up for “Unique Paths”:

    Now consider if some obstacles are added to the grids. How many unique paths would there be?

    An obstacle and empty space is marked as 1 and 0 respectively in the grid.

    For example,

    There is one obstacle in the middle of a 3x3 grid as illustrated below.

    [
    [0,0,0],
    [0,1,0],
    [0,0,0]
    ]

    The total number of unique paths is 2.

    Note: m and n will be at most 100.

    # 有障碍的棋盘格路径问题,考虑到如果在边界上有障碍,那么整个边界在障碍之后都是不可达的,所以用了本位置的obstacleGrid值乘以前面一个位置的值
    # 保证后面的都被封死,在非边界的地方,除了判断此处是否有障碍如有则置零外,其余同前。
    class Solution(object):
        def uniquePathsWithObstacles(self, obstacleGrid):
            """
            :type obstacleGrid: List[List[int]]
            :rtype: int
            """
            m = len(obstacleGrid)
            n = len(obstacleGrid[0])
            ret = [[1 for i in range(n)] for i in range(m)]
            if obstacleGrid[0][0] : return 0        
            for i in range(1, m):
                ret[i][0] = ret[i-1][0] * (1 - obstacleGrid[i][0])
            for j in range(1, n):
                ret[0][j] = ret[0][j-1] * (1 - obstacleGrid[0][j])        
            for i in range(1,m):
                for j in range(1,n):
                    ret[i][j] = ret[i-1][j] + ret[i][j-1] if not obstacleGrid[i][j] else 0
            return ret[-1][-1]

    64. Minimum Path Sum

    Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.

    Note: You can only move either down or right at any point in time.

    Example 1:

    [[1,3,1],
    [1,5,1],
    [4,2,1]]

    Given the above grid map, return 7. Because the path 1→3→1→1→1 minimizes the sum.

    # 和前面的类似,用DP,程序如下:
    class Solution(object):
        def minPathSum(self, grid):
            """
            :type grid: List[List[int]]
            :rtype: int
            """
            if not grid : return None
            m = len(grid)
            n = len(grid[0])
            ret = [[0 for i in range(n)] for i in range(m)]
            ret[0][0] = grid[0][0]
            for idx in range(1, m):
                ret[idx][0] = ret[idx-1][0] + grid[idx][0]
            for idy in range(1, n):
                ret[0][idy] = ret[0][idy-1] + grid[0][idy]
            for i in range(1,m):
                for j in range(1,n):
                    ret[i][j] = min(ret[i-1][j], ret[i][j-1]) + grid[i][j]
            return ret[-1][-1]

    71. Simplify Path

    Given an absolute path for a file (Unix-style), simplify it.

    For example,
    path = “/home/”, => “/home”
    path = “/a/./b/../../c/”, => “/c”

    click to show corner cases.
    Corner Cases:

    Did you consider the case where path = "/../"?
    In this case, you should return "/".
    Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/".
    In this case, you should ignore redundant slashes and return "/home/foo".
    
    class Solution(object):
        def simplifyPath(self, path):
            """
            :type path: str
            :rtype: str
            """
            pa = path.split('/')
            ret = []
            for itm in pa:
                if itm == '' or itm == '.':
                    continue
                elif itm == '..':
                    if ret : ret = ret[:-1]
                else: ret.append(itm)
            return '/' + '/'.join(ret)

    73. Set Matrix Zeroes

    Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place.

    click to show follow up.
    Follow up:

    Did you use extra space?
    A straight forward solution using O(mn) space is probably a bad idea.
    A simple improvement uses O(m + n) space, but still not the best solution.
    Could you devise a constant space solution?

    # 为了避免我们对行列置零的0和原有的0混淆,我们先将行列置零得到的0用'0' 字符串代替,最后再统一改成int
    class Solution(object):
        def setZeroes(self, matrix):
            """
            :type matrix: List[List[int]]
            :rtype: void Do not return anything, modify matrix in-place instead.
            """
            m, n = len(matrix), len(matrix[0])
            for i in range(m):
                for j in range(n):
                    if matrix[i][j] == 0:
                        for row in range(m):
                            if not matrix[row][j] == 0:
                                matrix[row][j] = '0'
                        for col in range(n):
                            if not matrix[i][col] == 0:
                                matrix[i][col] = '0'
            for i in range(m):
                for j in range(n):
                    if matrix[i][j] == '0':
                        matrix[i][j] = 0

    74. Search a 2D Matrix

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:

    Integers in each row are sorted from left to right.
    The first integer of each row is greater than the last integer of the previous row.
    

    For example,

    Consider the following matrix:

    [
    [1, 3, 5, 7],
    [10, 11, 16, 20],
    [23, 30, 34, 50]
    ]

    Given target = 3, return true.

    # 此题较简单,注意考虑边界条件,如[]和[[]]一类,提前加以判断。
    # 不过此题有更快的解法,就是根据这个矩阵的特殊情况,把它看成是一个有序的list,用binary search来做,只要做好矩阵下标和列表下标的对应即可。
    class Solution(object):
        def searchMatrix(self, matrix, target):
            """
            :type matrix: List[List[int]]
            :type target: int
            :rtype: bool
            """
            if not matrix or not matrix[0] : return False
            m, n = len(matrix), len(matrix[0])
            if target < matrix[0][0] or target > matrix[-1][-1] : return False
            for i in range(m):
                if matrix[i][0] <= target <= matrix[i][-1]:
                    break
            for j in range(n):
                if matrix[i][j] == target : return True
            return False

    75. Sort Colors

    Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue.

    Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.

    Note:
    You are not suppose to use the library’s sort function for this problem.

    click to show follow up.

    Follow up:
    A rather straight forward solution is a two-pass algorithm using counting sort.
    First, iterate the array counting number of 0’s, 1’s, and 2’s, then overwrite array with total number of 0’s, then 1’s and followed by 2’s.

    Could you come up with an one-pass algorithm using only constant space?

    # counting sort是一个直接的方法,但是会有空间开销,而且是two-pass的
    # 实际上这个是一个经典问题,叫做“荷兰国旗问题”,有一种经典的one-pass的in-place的通过分区和swap来做到的排序算法
    # 简单来讲就是将整个序列分成四个部分,[0,bot-1], [bot,mid-1], [mid, top], [top+1, n-1]
    # 这四个区块里分别盛着red,white,unknown,blue(实际上一开始看到这三种颜色就觉得可能是个经典问题,泛斯拉夫国旗色嘛。。。)
    # 我们通过一步步缩小unknown区域实现排序,缩小方法是这样:首先看到mid指向的元素,如果是red,那么就和bot交换一下,那么bot就要右移一个,同时
    # mid也要右移一个;如果是white,mid++即可,因为它自动延伸了第二段的长度;如果是blue,和top交换,并把top--。
    # 为啥在等于blue的时候不把mid++呢?因为第一种是确定的,swap的两个数一定是1和2,那么把1移到222……2左边,2移到222……2的右边,分界线需要都
    # 移动一下;而第二种显然;第三种将1与unknown中的最后一个交换,得到的结果是,我们无法知道交换后的mid指向的是多少,因此还需要判断。所以不+1
    # 经典算法就是6,简单好写好理解,一遍就AC了
    class Solution(object):
        def sortColors(self, nums):
            """
            :type nums: List[int]
            :rtype: void Do not return anything, modify nums in-place instead.
            """
            bot, mid, top = 0, 0, len(nums) - 1
            while mid <= top :
                if nums[mid] == 0:
                    nums[bot], nums[mid] = nums[mid], nums[bot]
                    bot += 1
                    mid += 1
                elif nums[mid] == 1:
                    mid += 1
                else:
                    nums[mid], nums[top] = nums[top], nums[mid]
                    top -= 1

    77. Combinations

    Given two integers n and k, return all possible combinations of k numbers out of 1 … n.

    For example,
    If n = 4 and k = 2, a solution is:

    [
    [2,4],
    [3,4],
    [2,3],
    [1,2],
    [1,3],
    [1,4],
    ]

    # 又一个典型的backtracking问题。。。基本都是固定的模板和套路。。。
    # dfs或者helper函数中要有如下几项:nums,这是原始数据, start_id,表示该次从哪个位置开始分支,实际上就是该次的子树的根,path是每一次的结果
    # res是最后返回的结果,res每当path符合要求就append一下,这是dfs最先需要判断的。
    # 另外,该题目如果不加上if k > len(nums) - idx : return 从而提前结束判断并return的话会有TLE,所以早剪枝是有用的。
    class Solution(object):
        def combine(self, n, k):
            """
            :type n: int
            :type k: int
            :rtype: List[List[int]]
            """
            res = []
            nums = range(1, n+1)
            self.dfs(nums, 0, [], res, k)
            return res
    
        def dfs(self, nums, idx, path, res, k):
            if k > len(nums) - idx : return
            if k == 0:
                res.append(path)
                return
            for i in range(idx, len(nums)):
                self.dfs(nums, i+1, path + [nums[i]], res, k-1)

    又10题了吧。。。记录一下。
    2018年03月31日00:52:24

  • 相关阅读:
    Appium教程
    ES6对象类型判断
    MyBatisPlus的时间段和模糊查询
    一个div中多个元素垂直居中的一种解决办法
    @JsonFormat与@DateTimeFormat注解的使用
    java日期类型对象通过mybatis向数据库中的存取
    Vue.js单向绑定和双向绑定实例分析
    Maven的使用
    如何将本地的项目提交到码云的远程仓库
    Linux CentOS7 的安装
  • 原文地址:https://www.cnblogs.com/morikokyuro/p/13256756.html
Copyright © 2011-2022 走看看