Leetcode (python实现)

Leetcode

1.两数之和

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。

你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        dict={}
        for i in range(len(nums)):
            if nums[i] in dict:
                return [dict[nums[i]],i]
            else:
                dict[target-nums[i]]=i

2.两数相加 Add Two Numbers

You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8

#python
class ListNode:
    def __init__(self,x):
        self.val=x
        self.next=None

class Solution:
    def addTwoNumbers(self,l1,l2):
        p=result=ListNode(-1)
        flag=0
        while l1 and l2:
            sum=l1.val+l2.val+flag
            flag=int(sum/10)
            ptemp=ListNode(sum%10)
            p.next=ptemp

            p=p.next
            l1=l1.next
            l2=l2.next

        temp1=l1 or l2

        while temp1:
            sum=temp1.val+flag
            flag=int(sum/10)
            ptemp=ListNode(sum%10)
            p.next=ptemp

            p=p.next
            temp1=temp1.next
        if flag:
            p.next=ListNode(flag)
        return result.next

3.无重复字符的最长子串

给定一个字符串,找出不含有重复字符的最长子串的长度。

示例 3:

输入: "pwwkew"
输出: 3
解释: 无重复字符的最长子串是 "wke",其长度为 3。
     请注意,答案必须是一个子串,"pwke" 是一个子序列 而不是子串。
class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        # s为空的情况
        if not s:
            return 0
        longestlenth = 1 # 非空子字符串的长度最小为1
        substr = "" # 子字符串
        for item in s:
            if item not in substr:
                substr += item
            else:
                if len(substr) > longestlenth:
                    longestlenth = len(substr)
                # 应该从重复的下一个字符开始继续判断
                substr += item
                substr = substr[substr.index(item)+1:]
        if len(substr) > longestlenth:
            longestlenth = len(substr)
        return longestlenth

4.两个排序数组的中位数

给定两个大小为 m 和 n 的有序数组 nums1nums2

请找出这两个有序数组的中位数。要求算法的时间复杂度为 O(log (m+n)) 。

你可以假设 nums1nums2 不同时为空。

class Solution:
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        i=0
        j=0
        c=[]
        while i<len(nums1) and j<len(nums2):
            if nums1[i]>nums2[j]:
                c.append(nums2[j])
                j+=1
            else:
                c.append(nums1[i])
                i+=1
        while i<len(nums1):
            c.append(nums1[i])
            i+=1
        while j<len(nums2):
            c.append(nums2[j])
            j+=1
        index = int(len(c) / 2)
        if len(c)%2!=0:
            return c[index]
        else:
            return (c[index-1]+c[index])/2

5.最长回文子串

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。

**算法一:**枚举回文串的中点,这里要分为两种情况,一种是回文串长度是奇数的情况,另一种是回文串长度是偶数的情况,枚举中点再判断是否是回文串,这样能把算法的时间复杂度降为O(n^2),但是当n比较大的时候仍然无法令人满意。

思路:对于每个子串的中心(可以是一个字符,或者是两个字符的间隙,比如串abc,中心可以是a,b,c,或者是ab的间隙,bc的间隙)往两边同时进行扫描,直到不是回文串为止。假设字符串的长度为n,那么中心的个数为2n-1(字符作为中心有n个,间隙有n-1个)。对于每个中心往两边扫描的复杂度为O(n),所以时间复杂度为O((2n-1)*n)=O(n^2),空间复杂度为O(1)。 Tips: 这样解决可以把奇偶相对统一起来,一起解决。

def longestPalindrome4(s):
    len_s=len(s)
    if len_s==0:
        return ''
    maxlen=0
    res=''
    for i in range(2*len_s-1):
        left=i//2          #i 能被2整除的  都是原来字符串里的字符
        right=i//2
        if i%2==1:            #这个i代表的字符为字符之间的间隙
            right=right+1
        sample_s=lengthOfPalindrome(s,left,right)
        if maxlen<len(sample_s):
            maxlen=len(sample_s)
            res=sample_s

    return res

##寻找以left和right为中心的最长回文子串
def lengthOfPalindrome(s,left,right):

    while (left>=0 and right<len(s) and s[left]==s[right]):
        left=left-1
        right=right+1

    return s[left+1:right]

6.Z字形变换

class Solution:
    def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """
        # 若行数为1,直接输出即可
        if numRows == 1:
            return s

        # resultlist为结果的列表形式
        resultlist = []
        gap = 2 * numRows - 2
        # 用嵌套循环完成计算
        for i in range(0, numRows):
            temp1 = i
            temp2 = gap - i
            # 分两种情况,情况1:第0行和第numRows行。temp1为主列的循环
            if temp1 == 0 or temp1 == numRows - 1:
                while temp1 < len(s):
                    resultlist.append(s[temp1])
                    temp1 = temp1 + gap
            # 情况二:除首尾行外的其他行。temp1为主列的循环,temp2为插入元素的循环
            else:
                while temp1 < len(s):
                    resultlist.append(s[temp1])
                    temp1 = temp1 + gap
                    if temp2 < len(s):
                        resultlist.append(s[temp2])
                        temp2 = temp2 + gap
        # resultst为未最终返回结果字符串结果
        resultstr = ''.join(resultlist)
        return resultstr

7.反转整数

给定一个 32 位有符号整数,将整数中的数字进行反转。

def reverse(x):
    flag=1
    if x<0:
        flag=-1
        x = -x
    result=0

    while x!=0:
        result=result*10+x%10
        x=int(x/10)

    result=result*flag
    return result if result<2**31-1 and result>-2**31 else 0

8.字符串转整数 (atoi)

实现 atoi,将字符串转为整数。

class Solution:
    def myAtoi(self, str):
        """
        :type str: str
        :rtype: int
        """
        str=str.strip()
        if str=='':
            return 0
        INT_MAX = 2147483647
        INT_MIN = -2147483648
        result=0
       
        flag=1
        if str[0]=='-':
            str=str[1:]
            flag=-1
        elif str[0]=='+':
            str=str[1:]
        for item in str:
            if item>='0'and item<='9':
                result = result * 10 + ord(item)-ord('0')
            else:
                break

        result=result * flag
        result=result if result<=INT_MAX else INT_MAX
        result=result if result>=INT_MIN else INT_MIN
        return result

9.回文数

判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

转换成字符串的:


class Solution:

    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        num=0
        if(x<0):return False
        if int(str(x))==int(str(x)[::-1]):
            return True
        return False

然后是不转换成字符串:


class Solution:

    def isPalindrome(self, x):
        """
        :type x: int

        :rtype: bool

        """
        num=0
        temp=x
        if x<0: return False
        while x!=0:
            num=num*10+x%10
            x=x//10
        if temp==num:return True
        return False

11.盛最多水的容器

给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

**说明:**你不能倾斜容器,且 n 的值至少为 2。

def maxArea(height):
    left,right=0,len(height)-1
    maxS=0
    while left<right:
        h=min(height[left],height[right])
        maxS=max(maxS,h*(right-left))
        if height[left]<height[right]:
            left+=1
        else:
            right-=1
    return maxS

12.整数转罗马数字

class Solution(object):
    def intToRoman(self, num):
        """
        :type num: int
        :rtype: str
        """
        if num > 3999 or num < 1:
            return 0
        # 字典是无序的,所以不使用字典
        # 注意这里一定要是倒序,否则执行会有问题,让数从大往小查找适合的罗马数
        num_tuple = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
        roman_tuple = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']
        # 记录结果的字符串
        result_str = ""
        # 从整数的列表中开始遍历
        for i in range(len(num_tuple)):
            # 从大往小开始判断,num小于当前数则进行下一次循环
            # num大于当前数则进行减法运算,并取出相应位置的Roman数
            while num >= num_tuple[i]:
                num -= num_tuple[i]
                result_str += roman_tuple[i]
        return result_str

13.罗马数转整数

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

14.最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""

//自己的
def longestCommonPrefix(strs):
    if strs=='':
        return ""
    temp=strs[0]
    commonPrefix=''
    for item in strs:
        i, j = 0, 0
        commonPrefix=''
        while i<len(item) and j<len(temp):
            if item[i]==temp[j]:
                commonPrefix+=item[i]
                i=i+1
                j=j+1
            else:
                break
        temp = commonPrefix
    return commonPrefix

//别人的

class Solution:
    def longestCommonPrefix(self, strs):
        """
        :type strs: List[str]
        :rtype: str
        """
        res = ""
        if len(strs) == 0:
            return ""
        for each in zip(*strs):  # zip()函数用于将可迭代对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表
            if len(set(each)) == 1:  # 利用集合创建一个无序不重复元素集
                res += each[0]
            else:
                return res
        return res

15.三数之和

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 *a,b,c ,*使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

**注意:**答案中不可以包含重复的三元组。

看到这道题目,我回想了leetcode的第一题。第一题是给出一个数组和一个target,找出数组的两个数使得这两个数等于target。在第一题中,我提到了”夹逼定理“。这里这个定理就可以用了。首先,我们将输入的数组nums排序。然后,从头开始取出一个数,nums[i],在nums[i+1:]中用夹逼定理找出num[j],numsk使得他们的和为0- nums[i]。然后将[nums[i],nums[j],nums[k]] append到答案数组。由于会存在多个组合使得nums[i] + nums[j] + nums[k] = 0,所以在比较的时候,如果nums[j] + nums[k] < 0- nums[i]时候,j += 1;如果nums[j] + nums[k] > 0 - nums[i]时候,k -= 1;如果nums[j] + nums[k] == 0 - nums[i]的时候,一直j += 1,k -= 1直到nums[j] != nums[j - 1]和nums[k] != nums[k + 1]。要注意的是,为了避免出现重复的组合,那么i + 的时候也要一直加到nums[i] != nums[i - 1]

class Solution:
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = []
        nums.sort()
        for i in range(0, len(nums)):
            if i > 0 and nums[i] == nums[i - 1]:
                continue
            target = 0 - nums[i]
            start, end = i + 1, len(nums) - 1
            while start < end:
                if nums[start] + nums[end] > target:
                    end -= 1  
                elif nums[start] + nums[end] < target:
                    start += 1
                else:
                    res.append((nums[i], nums[start], nums[end]))
                    end -= 1
                    start += 1
                    while start < end and nums[end] == nums[end + 1]:
                        end -= 1
                    while start < end and nums[start] == nums[start - 1]:
                        start += 1
        return res

16.最接近的三数之和

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

class Solution:
    def threeSumClosest(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums.sort()
        res=sum(nums[:3])
        min=abs(target-res)
        for i in range(len(nums)):
            start=i+1
            end=len(nums)-1
            while start<end:
                sumVal=nums[start]+nums[end]+nums[i]
                diff=abs(target-sumVal)
                if diff<min:
                    min=diff
                    res=sumVal
                if sumVal>target:
                    end-=1
                else:
                    start+=1
        return res

17.电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母

[外链图片转存失败(img-Y6c7FKnN-1562156315614)(http://upload.wikimedia.org/wikipedia/commons/thumb/7/73/Telephone-keypad2.svg/200px-Telephone-keypad2.svg.png)]

def letterCombinations(digits):
    if not digits:
        return []
    digit2chars = {
        '2': 'abc',
        '3': 'def',
        '4': 'ghi',
        '5': 'jkl',
        '6': 'mno',
        '7': 'pqrs',
        '8': 'tuv',
        '9': 'wxyz'
    }
    res = [i for i in digit2chars[digits[0]]]
    for i in digits[1:]:
        res = [m + n for m in res for n in digit2chars[i]]
    return res

递归方法:

def letterCombinations( digits):
    """
    :type digits: str
    :rtype: List[str]
    """
    # 创建字母对应的字符列表的字典
    dic = {'2': ['a', 'b', 'c'],
           '3': ['d', 'e', 'f'],
           '4': ['g', 'h', 'i'],
           '5': ['j', 'k', 'l'],
           '6': ['m', 'n', 'o'],
           '7': ['p', 'q', 'r', 's'],
           '8': ['t', 'u', 'v'],
           '9': ['w', 'x', 'y', 'z'],
           }
    # 存储结果的数组
    ret_str = []
    if len(digits) == 0: return []
    # 递归出口,当递归到最后一个数的时候result拿到结果进行for循环遍历
    if len(digits) == 1:
        return dic[digits[0]]
    # 递归调用
    result = letterCombinations(digits[1:])
    # result是一个数组列表,遍历后字符串操作,加入列表
    for r in result:
        for j in dic[digits[0]]:
            ret_str.append(j + r)
    return ret_str

链表的创建与基本操作

class ListNode(object):
    def __init__(self,x,p=0):
        self.val=x
        self.next=p


class LinkList(object):
    def __init__(self):
        self.head=None
    #链表初始化
    def initList(self,data):
        self.head=ListNode(data[0])
        p=self.head
        for i in data[1:]:
            node=ListNode(i)
            p.next=node
            p=p.next
    #链表判空
    def isEmpty(self):
        if self.head.next==0:
            print('empty list')
        else:
            return 0

    #取链表长度
    def getLength(self):
        if self.isEmpty():
            exit(0)
        p=self.head
        len=0
        while p:
            len+=1
            p=p.next
        return len

    #遍历链表
    def travelist(self):
        if self.isEmpty():
            exit(0)
        p=self.head
        while p:
            print(p.val)
            p=p.next

    #链表插入数据函数
    def insertElem(self,key,index):
        if self.isEmpty():
            exit(0)
        if index<0 or index>self.getLength()-1:
            print('\rKey error!')
            exit(0)
        count=0
        node=ListNode(key)
        p=self.head
        while p:
            if count==index:
                break
            p=p.next
            count+=1
        temp=p.next
        p.next=node
        node.next=temp

    #删除数据
    def deleteElem(self,index):
        if self.isEmpty():
            exit(0)
        if index<0 or index>self.getLength()-1:
            print('\r Value error')
            exit(0)

        p=self.head
        i=0
        while p.next:
            pre=p
            p=p.next
            i+=1
            if i==index:
                pre.next=p.next
                p=None
                return 1


nums=[1,2,3,4,5]
l=LinkList()
l.initList(data=nums)
l.deleteElem(2)
l.travelist()

19.删除链表的倒数第N个节点

自己的

class Solution:
    def removeNthFromEnd(self, head, n):
        """
        :type head: ListNode
        :type n: int
        :rtype: ListNode
        """
        p1=head
        p2=head
        len=0
        i=0
        while p1:
            len+=1
            p1=p1.next
        index=len-n
        if index==0:
            head=p2.next
            p2=None
            return head
        while p2.next:
            pre=p2
            p2=p2.next
            i+=1
            if i==index:
                pre.next=p2.next
                p2=None
                return head

别人的

class Solution:
    def removeNthFromEnd(self, head, n):
        """
        :type head: ListNode
        :type n: int
        :rtype: ListNode
        """
        pre = head
        end = head
        for _ in range(n):
            end = end.next
        if end is None:  # 需要删除的节点为第一个节点时,即返回第二个节点为头节点的链表
            return head.next
        while end.next is not None:
            pre = pre.next
            end = end.next
        pre.next = pre.next.next 
        return head

20.有效的括号

给定一个只包括 '('')''{''}''['']' 的字符串,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。

  1. 左括号必须以正确的顺序闭合。

注意空字符串可被认为是有效字符串。

自己的

class Solution:
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        if len(s)%2!=0:
            return False
        dic={"(":1,")":-1,"[":2,"]":-2,"{":3,"}":-3}
        rtn=True
        i=0
        stack=[]
        for item in s:
            if dic[item]>0:
                stack.append(dic[item])
            else:
                if not stack or stack[len(stack)-1]+dic[item]!=0:
                    return False
                else:
                    stack.pop()
        return stack==[]

别人的

class Solution:
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        if len(s)%2!=0:
            return False
        dic={"(":")","[":"]","{":"}"}
        stack=[]
        for item in s:
            if item in dic:
                stack.append(item)
            else:
                if not stack or dic[stack.pop()]!=item:
                    return False
        return stack==[]

21合并两个有序链表

class Solution:
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        head=ListNode(0)
        p=head
        while l1 and l2:
           if l2.val>l1.val:
               p.next=l1
               l1=l1.next
               p = p.next
           else:
               p.next=l2
               l2=l2.next
               p = p.next
        while l1:
            p.next=l1
            l1=l1.next
            p=p.next
        while l2:
            p.next=l2
            l2=l2.next
            p=p.next
        return head.next

22.括号生成

给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。

例如,给出 n = 3,生成结果为:

[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]

如果左括号还有剩余,则可以放置左括号,如果右括号的剩余数大于左括号,则可以放置右括号。

def generateParenthesis(n):
    ret=[]
    generate('',n,n,ret)
    return ret

def generate(mstr,r,l,ret):
    if r==0 and l==0:
        ret.append(mstr)
        return
    if l>0:
        generate(mstr+'(',r,l-1,ret)
    if r>0 and r>l:
        generate(mstr+')',r-1,l,ret)

23.合并K个排序链表

class Solution:
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        if len(lists)<1:
            return []
        head=ListNode(0)
        head.next=lists[0]
        for lst in lists[1:]:
            node=head
            item=lst
            while item and node.next:
                if node.next.val>item.val:
                    temp=node.next
                    node.next=ListNode(item.val)
                    node=node.next
                    node.next=temp
                    item=item.next
                else:
                    node=node.next
            if item:
                 node.next=item
        return head.next

23.删除排序数组中的重复项

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

24.两两交换链表中的节点

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。

class Solution:
    def swapPairs(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head:
            return head
        rtn=ListNode(0)
        cur=rtn
        cur.next=head
        while cur.next and cur.next.next:
            p1=cur.next
            p2=p1.next
            temp=p2.next
            p1.next=temp
            p2.next=p1
            cur.next=p2
            cur=p1
        return rtn.next

链表翻转

def reverseList(head):
    if not head:
        return None
    rtnList=ListNode(0)
    cur=rtnList
    cur.next=head
    cur=cur.next
    while cur.next:
        p1=cur
        p2=p1.next
        temp=p2.next
        p1.next=temp
        p2.next=rtnList.next
        rtnList.next=p2
    return rtnList.next

25.k个一组翻转链表


26.删除数组中重复的数

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

27.移除元素

class Solution:
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        if not nums:
            return 0
        s=0
        for item in nums:
            if item!=val:
                nums[s]=item
                s+=1
        return s
        

28.实现 strStr() 函数。

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1

思路1:

扫描haystack,当遇到与needle首字符相同的位置时,检查haystack从该位置开始的与needle长度相同的块,与needle是否相同。

class Solution:
    def strStr(self, haystack, needle):
        """
        :type haystack: str
        :type needle: str
        :rtype: int
        """
        
        if not needle:
            return 0
        for i in range(len(haystack) - len(needle) + 1):
            if haystack[i] == needle[0]:
                j = 1
                while j < len(needle) and haystack[i+j] == needle[j]:
                    j += 1
                if j == len(needle):
                    return i
        return -1

思路2:

class Solution(object):
    def strStr(self, haystack, needle):
        """
        :type haystack: str
        :type needle: str
        :rtype: int
        """
        for i in xrange(len(haystack) - len(needle) + 1):
            if haystack[i:i+len(needle)] == needle:
                return i
        return -1
class Solution(object):
    def strStr(self, haystack, needle):
        """
        :type haystack: str
        :type needle: str
        :rtype: int
        """
        return haystack.find(needle)

29.两数相除

给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。

返回被除数 dividend 除以除数 divisor 得到的商。


33.搜索旋转排序数组

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1

你可以假设数组中不存在重复的元素。

你的算法时间复杂度必须是 O(log n) 级别。

class Solution:
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        if not nums:
            return -1
        index=-1
        end=len(nums)-1
        val=(nums[0]+nums[end])/2
        start=0
        mid=0
        while start<end:
            mid=(start+end)//2
            if nums[mid]>nums[end]:
                start=mid+1
            else:
                end=mid
        pos=start
        s= 0
        e=0
        if target>=nums[0]:
            s=0
            e=pos
        if target<=nums[len(nums)-1]:
            s=pos
            e=len(nums)
        index=self.binary_search(nums[s:e],target)
        if index>=0:
            index=index+s
        return index
    
    def binary_search(self,nums,target):
        index=-1
        start=0
        end=len(nums)-1
        while start<=end:
            mid=(start+end)//2
            if nums[mid]<target:
                start=mid+1
            elif nums[mid]>target:
                end=mid-1
            else:
                index = mid
                break
        return index

34. 在排序数组中查找元素的第一个和最后一个位置

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

你的算法时间复杂度必须是 O(log n) 级别。

如果数组中不存在目标值,返回 [-1, -1]

class Solution(object):

    def searchRange(self, nums, target):

        """

        :type nums: List[int]

        :type target: int

        :rtype: List[int]

        """

        if len(nums) == 0:

            return [-1,-1]

        elif target < nums[0] or target > nums[-1]:

            return [-1,-1]

        else:

            l, r = 0, len(nums) - 1

            while l <= r:

                mid = (l + r) // 2

                if target > nums[mid]:

                    l = mid + 1

                elif target < nums[mid]:

                    r = mid - 1

                #当找到相等的值时,把左右指针合并并分别向左向右依次遍历找出上下限

                elif target == nums[mid]:

                    l = r = mid

                    while l-1 >= 0 and nums[l-1] == target:

                        l -= 1

                    while r+1 <= len(nums)-1 and nums[r+1] == target:

                        r += 1

                    return [l,r]

        return [-1,-1]

        

35.搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

你可以假设数组中无重复元素。

我的:

class Solution:
    def searchInsert(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        for i in range(len(nums)):
            if target<=nums[i]:
                return i
        return i+1
        

别人的:二分查找


class Solution:
    def searchInsert(self, nums, target):
        #因为数组有序,所以可以去除特殊情况
        if target < nums[0]:

            return 0

        elif target > nums[-1]:

            return len(nums)        

        l = 0

        r = len(nums) - 1

        #先用二分找

        while l<=r:

            mid = (l+r)//2

            if nums[mid] < target:

                l = mid+1

            elif nums[mid] > target:

                r = mid-1

            else:

                return mid


        #如果跳出while时是l = mid + 1后导致的,说明我们的mid小于target,返回l的值

        if l > mid:

            return l

        #如果跳出while时是r = mid - 1后导致的,说明我们的mid大于target,所以返回r+1,也就是mid

        if r < mid:

            return r+1

未完待续…

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值