GaryLeetCode学习笔记·壹(第十周)

1,two sum

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1]

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        for i in nums:
            for j in range(nums.index(i)+1,len(nums)):
                if i+nums[j]==target:
                    return(nums.index(i),j)
class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        n=-1
        lists=[]
        max=target-min(nums)
        for num in nums:
            n=n+1
            if num <=max:
                lists.append(n)
            for i in lists:
                for j in lists:
                    if (i!=j) and (target==nums[i]+nums[j]):
                        return[i,j]

为数不多的不需要补充新知识就能解决的一道题,关键点之一是python中的范围是左开右闭的,且列表中第一个数的下标为0.第一种方法大意就是对于nums中的每个数字i,判断位置在i后面的每个数字分别于i相加是否等于所给的target,返回满足条件的两个数的下标即可;但第二种方法通过了29个测试用例中的28个,为何超出时间限制一直没有搞太清楚,碰巧看到西交电信学院卫老师的CSDN博客:老卫带你学—leetcode刷题(1.两数之和)

可是在运行的时候就因为时间过长而报错,想想也是,两个for循环,其时间复杂度为O(n^2),不死才怪呢。

然后卫老师指出了另一种做法,

通过加入字典映射,将数据存入字典之中,然后遍历数组,并且用目标数减去每个单元数,然后判断是否存在于字典中。

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        arr = {}
        length = len(nums)
        for i in range(length):
            if (target - nums[i]) in arr:
                return [arr[target - nums[i]], i]
            arr[nums[i]] = i
--------------------- 
作者:老卫带你学 
来源:CSDN 
原文:https://blog.csdn.net/yixieling4397/article/details/82843398 
版权声明:本文为博主原创文章,转载请附上博文链接!

7,reverse integer

Given a 32-bit signed integer, reverse digits of an integer.

Example 1:

Input: 123
Output: 321
Example 2:

Input: -123
Output: -321
Example 3:

Input: 120
Output: 21
Note:
Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.

class Solution(object):
    def reverse(self, x):
        """
        :type x: int
        :rtype: int
        """
        if x<-pow(2,31) or x>pow(2,31)-1:
            return 0
        s=str(x)
        if len(s)==1:
            return x
        s=s[::-1]
        if s.startswith('0'):
            s=s.lstrip('0')
        if s.endswith('-'):
            s='-'+s.rstrip('-')
        i=int(s)
        if i<-pow(2,31) or i>pow(2,31)-1:
                return 0
        return i

由举例可知题目要求结果应在定义域内,保留原有符号,并舍掉首位的0,分别使用三个if语句即可解决。最后再用一个if检验反转后是否溢出即可。
要解决本题涉及到的知识点较多:

  1. 指数的表达方式power(a,b),其中a为底数,b为指数;
  2. 逆序显示的表示方法 [::-1]
    比如,a = [0,1,2,3,4,5,6,7,8,9]
    b = a[i:j] 表示复制a[i]到a[j-1],以生成新的list对象
    b = a[1:3] 那么,b的内容是 [1,2]
    当i缺省时,默认为0,即 a[:3]相当于 a[0:3]
    当j缺省时,默认为len(alist), 即a[1:]相当于a[1:10]
    当i,j都缺省时,a[:]就相当于完整复制一份a了
    b = a[i:j:s]这种格式,i,j与上面的一样,但s表示步进,缺省为1.
    所以a[i:j:1]相当于a[i:j]
    当s<0时,i缺省时,默认为-1. j缺省时,默认为-len(a)-1
    所以a[::-1]相当于 a[-1:-len(a)-1:-1],也就是从最后一个元素到第一个元素复制一遍。
    字符串的语法截取格式 变量[头下标:尾下标:步长](仍满足左开右闭的传统)
  3. strip()该函数的作用是去除字符串开头和结尾处指定的字符,不会去除字符串中间对应的字符;调用该函数时,可设置传入参数或者不设置参数:若不传入字符,则默认去除字符串开头和结尾的空格或换行字符;若传入字符,则会依据传入的字符来进行去除操作。lstrip()和rstrip() 这两个函数和strip()基本是一样的,一个是去掉左边的(头部),一个是去掉右边的(尾部)。在题中调用该函数前,要用str()函数将x转换为字符串才行。
  4. startswith(str, beg=0,end=len(string)) /endswith(…)方法用于检查字符串是否是以指定子字符串开头/结尾,如果是则返回 True,否则返回 False。如果参数 beg 和 end 指定值,则在指定范围内检查。

9,palindrome number

Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same backward as forward.

Example 1:

Input: 121
Output: true
Example 2:

Input: -121
Output: false
Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.
Example 3:

Input: 10
Output: false
Explanation: Reads 01 from right to left. Therefore it is not a palindrome.
Follow up:

Coud you solve it without converting the integer to a string?

class Solution(object):
    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        s=list(str(x))
        s1=s
        s1.reverse
        if s==s1:
            return True
        else:
            return False
         
class Solution(object):
    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        s=list(str(x))
        s1=list(str(x))
        s1.reverse()
        if s==s1:
            return True
        else:
            return False
         

解题大意就是将x字符串化放在列表中,应用reverse()函数反转,检查前后两列表是否相同。答案二为我对答案一的简化写法,但提交后答案二却显示解答错误,顿时凌乱了,求解答
收获:reverse()函数用于反向列表中元素。

13,roman-to-integer

Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.

Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
For example, two is written as II in Roman numeral, just two one’s added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II.

Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:

I can be placed before V (5) and X (10) to make 4 and 9.
X can be placed before L (50) and C (100) to make 40 and 90.
C can be placed before D (500) and M (1000) to make 400 and 900.
Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999.

Example 1:

Input: “III”
Output: 3
Example 2:

Input: “IV”
Output: 4
Example 3:

Input: “IX”
Output: 9
Example 4:

Input: “LVIII”
Output: 58
Explanation: C = 100, L = 50, XXX = 30 and III = 3.
Example 5:

Input: “MCMXCIV”
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

class Solution(object):
    def romanToInt(self, s):
        """
        :type s: str
        :rtype: int
        """
        sum=0
        convert={'M':1000,'D':500,'C':100,'L':50,'X':10,'V':5,'I':1}
        for i in range(len(s)-1):
            if convert[s[i]]<convert[s[i+1]]:
                sum=sum-convert[s[i]]
            else:
                sum=sum+convert[s[i]]
        return sum+convert[s[-1]]

本题很具有现实意义,但IV,IX等带有数字4,9的表示方法给本题平添难度
本题宜使用字典解决,

字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中。

根据题干,将所给的数字对应的key和value按格式输入字典中。在一个罗马数字中,小数与大数并排时,满足左加右减的(以大数为“参考系”),既可由此用for循环+if/else语句解决上述难点。为使if条件有意义,不应在循环中考虑最后一位数字,而是在最后返回时再加上。

14,longest-common-prefix

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

If there is no common prefix, return an empty string “”.

Example 1:

Input: [“flower”,“flow”,“flight”]
Output: “fl”
Example 2:

Input: [“dog”,“racecar”,“car”]
Output: “”
Explanation: There is no common prefix among the input strings.
Note:

All given inputs are in lowercase letters a-z.

class Solution(object):
    def longestCommonPrefix(self, strs):
        """
        :type strs: List[str]
        :rtype: str
        """
        if len(strs)==0:
            return''
        str=strs[0]
        Min=len(str)
        for i in range(1,len(strs)):
            j=0
            p=strs[i]
            while j<Min and j<len(p) and p[j]==str[j]:
                j+=1
            Min=min(Min,j)
        return str[:Min]
                

刚开始我始终认为return str[:j]即可,因为j不会大于Min。但经大神指出,strs中若仅有一个字符串,应该返回该字符串。与此同时存在着j的定义的for循环不会被执行,j没有定义从而导致错误。
感谢河北省信息竞赛省一得主、哈尔滨工业大学计算机系2018级李同欣大神,我的高中同窗好友,对我本题的帮助。

20,valid-parentheses

Given a string containing just the characters ‘(’, ‘)’, ‘{’, ‘}’, ‘[’ and ‘]’, determine if the input string is valid.

An input string is valid if:

Open brackets must be closed by the same type of brackets.
Open brackets must be closed in the correct order.
Note that an empty string is also considered valid.

Example 1:

Input: “()”
Output: true
Example 2:

Input: “()[]{}”
Output: true
Example 3:

Input: “(]”
Output: false
Example 4:

Input: “([)]”
Output: false
Example 5:

Input: “{[]}”
Output: true

class Solution(object):
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        dic={'(':')','[':']','{':'}'}
        stack=[]
        for current in s:
            if current in dic.keys():
                stack.append(current)
            elif current in dic.values():
                if len(stack) == 0 or dic.get(stack[-1]) != current:
                    return False
                else:
                    stack.pop()
        if len(stack)==0:
            return True
        else:
            return False

本题用到了栈结构,正好是大计基课程即将要讲到的。首先建立字典,左括号作为key,有括号作为value。对于s中的括号,若为左,入栈;若为右,再分类:(1)若空栈,则不存在一个左括号与之闭合,false,或者,用dic.get()函数查找栈顶对应的右括号(value),若不同,则虽闭合但类型不同,false。(2)否则,将上一级if中进栈的元素出栈。如果最终空栈,则证明左括号与相同类型的右括号闭合且左括号以正确的顺序闭合,true;反之,false。

26,remove-duplicates-from-sorted-array

Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length.

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

Example 1:

Given nums = [1,1,2],

Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively.

It doesn’t matter what you leave beyond the returned length.
Example 2:

Given nums = [0,0,1,1,1,2,2,3,3,4],

Your function should return length = 5, with the first five elements of nums being modified to 0, 1, 2, 3, and 4 respectively.

It doesn’t matter what values are set beyond the returned length.
Clarification:

Confused why the returned value is an integer but your answer is an array?

Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.

Internally you can think of this:

// nums is passed in by reference. (i.e., without making a copy)
int len = removeDuplicates(nums);

// any modification to nums in your function would be known by the caller.
// using the length returned by your function, it prints the first len elements.
for (int i = 0; i < len; i++) {
print(nums[i]);
}

class Solution(object):
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) <= 1:
            return len(nums)
        else:
            s = 0 
            for f in range(1, len(nums)):
                 if nums[s] != nums[f]:
                    s += 1
                    nums[s] = nums[f]
            return s + 1

前提给的是排序数组,注意审题,如给一般数组则很可能无解。本题要求十分怪异,要原地删除重复出现的元素,我认为就是应该一对一的进行元素替换,才能不占用额外的数组空间(通俗地讲,一个萝卜一个坑,萝卜可以变,但坑始终就那么多,不能再多了),且只返回新数组的长度。先讨论数组中有0或1个数情况,此时无需删除,直接输出长度即可;然后讨论有多个数的情况,对于数组中的某个数从头开始与后面的所有数分别比较,如果相同,则不改变;若不同,则用后者代替前者,下次从之前某个数的下一个开始比较。最终做了s次替换,即有s个不同的数,再加上第0个数本身,即s+1为新数组长度。(本题答案脑洞实在太大)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值