资讯专栏INFORMATION COLUMN

记录leetcode上的一些题

shixinzhang / 2306人阅读

摘要:此篇文章最先发布在我的博客上记录上的一些题,基本上是上的题,其他的我会标注出来,用的语言目前是写的代码很庸俗,请大神不要见笑题目罗马数字的规则如下罗马数字共有个,即和。在较大的罗马数字的左边记上较小的罗马数字,表示大数字减小数字。

此篇文章最先发布在我的博客mbinary上
   
记录OJ上的一些题,基本上是leetcode上的题,其他的我会标注出来,用的语言目前是python,写的代码很庸俗,请大神不要见笑(>_<)

# 2017-8-20

Integer to Roman

  题目

Given an integer, convert it to a roman numeral.
Input is guaranteed to be within the range from 1 to 3999.
罗马数字的规则如下:

罗马数字共有7个,即Ⅰ(1)、Ⅴ(5)、Ⅹ(10)、Ⅼ(50)、Ⅽ(100)、Ⅾ(500)和Ⅿ(1000)。按照下述的规则可以表示任意正整数。需要注意的是罗马数字中没有“0”,与进位制无关。一般认为罗马数字只用来记数,而不作演算。

重复数次:一个罗马数字重复几次,就表示这个数的几倍。

右加左减

在较大的罗马数字的右边记上较小的罗马数字,表示大数字加小数字。

在较大的罗马数字的左边记上较小的罗马数字,表示大数字减小数字。

左减的数字有限制,仅限于I、X、C。比如45不可以写成VL,只能是XLV

左减时不可跨越一个位值。比如,99不可以用IC( 100-1)表示,而是用XCIX([100-10]+[10-1])表示。(等同于阿拉伯数字每位数字分别表示。)

左减数字必须为一位,比如8写成VIII,而非IIX。

右加数字不可连续超过三位,比如14写成XIV,而非XIIII。(见下方“数码限制”一项。)

加线乘千
在罗马数字的上方加上一条横线或者加上下标的Ⅿ,表示将这个数乘以1000,即是原数的1000倍。同理,如果上方有两条横线,即是原数的1000000( {displaystyle 1000^{2}} 1000^{{2}})倍。

数码限制
同一数码最多只能连续出现三次,如40不可表示为XXXX,而要表示为XL。例外:由于IV是古罗马神话主神朱庇特(即IVPITER,古罗马字母里没有J和U)的首字,因此有时用IIII代替IV。

     思路
这道题还是蛮有意思的,同样用递归的方法,在了解拼写规则后,要从数值范围来判断罗马数字的结构,即取哪个字母?哪种组合?左或是右?
孪生题是Roman to Interger比较简单
  代码

#python
class Solution(object):
    def intToRoman(self, num):
        """
        :type num: int
        :rtype: str
        """
        dic = {0:"",1:"I",5:"V",10:"X",50:"L",100:"C",500:"D",1000:"M"}
        ks = [1,5,10,50,100,500,1000]
        
        def convert(num):
            if num in dic.keys():
                return dic[num]
            if num > 1000:
                n = int(num/1000)
                num -= n * 1000
                return  "M"*n + convert(num)
            n = 1000
            for i in ks:
                if i > num :
                    n = i
                    break
            exp = 1
            flag = False
            while exp <= n:   # judge if n is 10 exp k
                if exp == n:
                    flag = True
                    break
                exp *= 10
            if flag:
                small = n / 10
                if num >= 9 * small:
                    return dic[small] + dic[n] + convert(small -(n-num)) 
                else:
                    return dic[n/2] + convert(num - n/2)
            else:
                small = n / 5
                if n - small <= num :
                    return dic[small] + dic[n] + convert(small - (n-num))
                else:
                    n2 = int(num / small)
                    num -= n2 * small
                    return dic[small] * n2 + convert(num)
        return convert(num)             

word search

  题目

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

For example,
Given board =
[
  ["A","B","C","E"],
  ["S","F","C","S"],
  ["A","D","E","E"]
]
word = "ABCCED", -> returns true,
word = "SEE", -> returns true,
word = "ABCB", -> returns false.

     思路
这道题可以用递归函数来解决,注意到,eg从“a” 中判断是否有“aa” ,如果直接递归是返回true的,这不对,要就是说在一次判断中,已判断过的字母不能再判断,所以参数应该还有一个board,记录当前的字母状态,考虑到python是用的引用,传递参数时没有复制,我又不想额外再去复制board,就在函数中记下当前位置的字母,在函数调用结束再改回来的。哈哈!
  代码

#python
class Solution(object):
    def exist(self, board, word):
        """
        :type board: List[List[str]]
        :type word: str
        :rtype: bool
        """
        row = len(board)
        col = len(board[0])
        num = len(word)
        def find(r,c,n):
            if n == num-1 and board[r][c] == word[n]:
                return True
            if board[r][c] != word[n] or n == num-1:
                return  False
            tmp = board[r][c]    #save  the  val
            board[r][c] = 0
            if r < row-1 and find(r+1,c,n+1):
                return True
            if r > 0 and find(r-1,c,n+1):
                return True
            if c  0 and find(r,c-1,n+1):
                return True
            board[r][c] = tmp
            return False
        for i in range(row):
            for j in range(col):
                if find(i,j,0):
                    return True
        return False

# 2017-8-19

3 sum

  题目

Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note: The solution set must not contain duplicate triplets.

For example, given array S = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

    思路
最开始我想的就直接3重循环,再加判重的循环,暴力求解,当然超时了,要高于O(n3)。后来想到可以将正负数,0,分成三组来组合,然而最后两个数据过不了,在网上搜了一下,可以固定一个数,头尾双指针来移动,这是O(n2)。哎,折腾了一晚上,我好菜啊。 这是前几次的结果[站外图片上传中……(1)]

     代码 (分成正负0三组,写了很多判断语句,唉,庸俗的代码。 )

#python

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        
        rst = []
        zero = []   #zeros
        neg = []    #negative
        pos = []    #positive
        for i in (nums):
            if i < 0:
                neg.append(i)
            elif i > 0:
                pos.append(i)
            else:
                zero.append(i)
        if len(zero) > 2:
            rst.append([0,0,0])
        if neg == []  or  pos == []:
            return rst
        if zero != []:
            if len(neg) > len(pos):
                for i in pos:
                    if -i in neg:
                        rst.append([-i,0,i])
            else:
                for i in neg:
                    if -i in pos:
                        rst.append([i,0,-i])
        pos.sort()
        neg.sort()
        if len(pos) == 1 and len(neg) == 1:
            return rst
        elif len(pos) == 1 :
            tmp = len(neg) - 1
            while tmp > 0:
                sum = neg[tmp] + neg[tmp-1]
                if sum == - pos[0]:
                    rst.append([neg[tmp-1],neg[tmp],pos[0]])
                    break
                elif sum < - pos[0]:
                    break
                tmp -= 1
        elif len(neg) == 1:
            tmp = 0
            while tmp < len(pos) - 1 :
                sum = pos[tmp] + pos[tmp+1]
                if sum == - neg[0]:
                    rst.append([neg[0],pos[tmp],pos[tmp+1]])
                    break
                elif sum > - neg[0]:
                    break
                tmp -= 1
        sameI = []     #avoid test several same num
        for i in range(len(pos)-1):
            if i in sameI:
                continue
            sameI.append(i)
            sameJ=[]
            for j in range(i+1,len(pos)):
                if j in sameJ:
                    continue
                sameJ.append(j)
                sum = pos[i] + pos[j]
                for k in neg:
                    if   sum > -k:
                        break
                    elif sum == -k:
                        rst.append([k,pos[i],pos[j]])
        sameI = []
        for i in range(len(neg)-1):
            if i in sameI:
                continue
            sameI.append(i)
            sameJ=[]
            for j in range(i+1,len(neg)):
                if j in sameJ:
                    continue
                sameJ.append(j)
                sum = neg[i] + neg[j]
                for k in pos:
                    if   sum > -k:
                        break
                    elif sum == -k:
                        rst.append([neg[i],neg[j],k])
        fnl = []   
        for i in rst:
            if i not in fnl:
                fnl.append(i)
        return fnl 

    代码 (头尾双指针,过了,注意判重的方法,前一个用的if,后面在找到答案时用while)

#python
class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        rst=[]
        nums.sort()
        for i in range(len(nums)-2):
            if i > 0 and nums[i] == nums[i-1]:
                continue
            head = i+1
            tail = len(nums) - 1
            while head < tail:
                if nums[i] + nums[head] + nums[tail]  == 0:
                    rst.append([nums[i],nums[head],nums[tail]])
                    head += 1
                    tail -= 1
                    while head< tail and nums[head] == nums[head -1]:
            head = i+1
            tail = len(nums) - 1
            while head < tail:
                if nums[i] + nums[head] + nums[tail]  == 0:
                    rst.append([nums[i],nums[head],nums[tail]])
                    head += 1
                    tail -= 1
                    while head< tail and nums[head] == nums[head -1]:
                        head += 1
                    while head
2017-8-17

jump game

  题目

Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.

For example:

A = [2,3,1,1,4], return true.
A = [3,2,1,0,4], return false.

    思路
由于只有非负数,不能成功的点一定是当前位置为0,所以可以将列表中所以的0找出来,并记下位置(下标),然后从这个位置开始往前搜索,若存在能跳过此位置的点,则能跳过,去除这个0,一直跳过所有0

    代码

#python
    class Solution(object):
    def canJump(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """

        if len(nums) == 1:
            return True
        zeros = []
        for i,j in enumerate(nums):
            if j == 0:
                zeros.append(i)
        while zeros != []:
            i = zeros[0]
            tmp = i - 1
            flag = 0
            while tmp >= 0:
                if nums[tmp] > i-tmp  or nums[tmp]+tmp+1 >=len(nums):
                    flag = 1
                    break
                tmp -= 1
            if flag == 0 :
                return False
            del zeros[0]
            
        return True

super pow

  题目

Your task is to calculate ab mod 1337 where a is a positive integer and b is an extremely large positive integer given in the form of an array.

Example1:
a = 2

b = [3]
Result: 8

Example2:

a = 2
b = [1,0]
Result: 1024

  思路
这道题显然不能直接计算,可以用欧拉定理
对任意正整数a,正整数m,(a,m) = 1,ƒ(m) 为比m小的与m互质的(注意不一定是质数)正整数的个数,
则 aƒ(m) ≡ 1 (mod m) 。
再利用性质: a ≡ b (mod m) ,c ≡ d (mod m) ,则ac ≡ bd (mod m)
证明就不写了,打数学符号太累了(T^T),给个传送门吧--> 欧拉定理)

  代码

    #python
    class Solution(object):
    def superPow(self, a, b):
        """
        :type a: int
        :type b: List[int]
        :rtype: int
        """
        m = 1337
        if a % m == 0:
            return 0
        sum = 0
        for i in b:
            sum = 10 * sum + i    
        phi = 0
        for i in range(1,m):
            if (i % 7 != 0) and (i % 191 != 0):
                phi += 1
        sum = sum % phi
        return (a**sum) % 1337
        # if m a prime num ,use the small law of Fermat
        # else use the law of Euler
    

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/40754.html

相关文章

  • LeetCode 攻略 - 2019 年 8 月上半月汇总(109 攻略)

    摘要:每天会折腾一道及以上题目,并将其解题思路记录成文章,发布到和微信公众号上。三汇总返回目录在月日月日这半个月中,做了汇总了数组知识点。或者拉到本文最下面,添加的微信等会根据题解以及留言内容,进行补充,并添加上提供题解的小伙伴的昵称和地址。 LeetCode 汇总 - 2019/08/15 Create by jsliang on 2019-08-12 19:39:34 Recently...

    tracy 评论0 收藏0
  • LeetCode 攻略 - 2019 年 7 月上半月汇总(55 攻略)

    摘要:微信公众号记录截图记录截图目前关于这块算法与数据结构的安排前。已攻略返回目录目前已攻略篇文章。会根据题解以及留言内容,进行补充,并添加上提供题解的小伙伴的昵称和地址。本许可协议授权之外的使用权限可以从处获得。 Create by jsliang on 2019-07-15 11:54:45 Recently revised in 2019-07-15 15:25:25 一 目录 不...

    warmcheng 评论0 收藏0
  • LeetCode 攻略 - 2019 年 7 月下半月汇总(100 攻略)

    摘要:月下半旬攻略道题,目前已攻略题。目前简单难度攻略已经到题,所以后面会调整自己,在刷算法与数据结构的同时,攻略中等难度的题目。 Create by jsliang on 2019-07-30 16:15:37 Recently revised in 2019-07-30 17:04:20 7 月下半旬攻略 45 道题,目前已攻略 100 题。 一 目录 不折腾的前端,和咸鱼有什么区别...

    tain335 评论0 收藏0
  • 回溯算法讲解--适用于leetcode绝大多数回溯

    摘要:什么是回溯算法回溯法是一种系统搜索问题解空间的方法。解空间定义为与数字长度相同。最后,为什么要掌握回溯法因为懂了回溯法之后笔试里的很多题就算不了,起码成功运行到之间是没问题的。 什么是回溯算法?回溯法是一种系统搜索问题解空间的方法。为了实现回溯,需要给问题定义一个解空间。说到底它是一种搜索算法。只是这里的搜索是在一个叫做解空间的地方搜索。而往往所谓的dfs,bfs都是在图或者树这种数据...

    saucxs 评论0 收藏0
  • LeetCode 之 JavaScript 解答第104 —— 二叉树的最大深度

    摘要:小鹿题目二叉树的最大深度给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。求二叉树的深度,必然要用到递归来解决。分别递归左右子树。 Time:2019/4/22Title: Maximum Depth of Binary TreeDifficulty: MediumAuthor:小鹿 题目:Maximum Depth of Binary Tre...

    boredream 评论0 收藏0

发表评论

0条评论

shixinzhang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<