剑指offer Python2版

1. 二维数组中的查找

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

# -*- coding:utf-8 -*-
class Solution:
    # array 二维列表
    def Find(self, target, array):
        # write code here
        row = 0
        col = len(array[0])-1
        while(row >=0 and row <len(array) and col >= 0 and col < len(array[0])):
            if array[row][col] > target:
                col -= 1
            elif array[row][col] < target:
                row += 1
            else:
                return True
        return False

2. 替换空格

题目描述
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

# -*- coding:utf-8 -*-
class Solution:
    # s 源字符串
    def replaceSpace(self, s):
        # write code here
        s = s.replace(" ", "%20")
        return s

3. 从头到尾打印链表

题目描述
输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    # 返回从尾部到头部的列表值序列,例如[1,2,3]
    def printListFromTailToHead(self, listNode):
        # write code here
        res = []
        while(listNode):
            res.append(listNode.val)
            listNode = listNode.next
        #return res[::-1]  
        res.reverse()
        return res

4.重建二叉树

题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回构造的TreeNode根节点
    def reConstructBinaryTree(self, pre, tin):
        # write code here
        if len(pre)==0:
            return None
        root = TreeNode(pre[0])  #前序的第一个为根
        pos = tin.index(pre[0])   #中序找到根的位置
        root.left = self.reConstructBinaryTree(pre[1:pos+1], tin[:pos+1])
        root.right = self.reConstructBinaryTree(pre[pos+1:], tin[pos+1:])
        return root

5. 用两个栈实现一个队列

题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        #用lsit 来定义栈 push append   pop list.pop() 默认pop最后一个
        self.stack1 = [] 
        self.stack2 = []
    def push(self, node):
        # write code here
        self.stack1.append(node)
    def pop(self):
        # return xx
        if self.stack2:
            return self.stack2.pop()
        else:
            while(self.stack1):
                self.stack2.append(self.stack1.pop())
            return self.stack2.pop()
        

6. 旋转数组的最小数字

题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

链接:https://www.nowcoder.com/questionTerminal/9f3231a991af4f55b95579b44b7a01ba
来源:牛客网
mid = low + (high - low)/2
需要考虑三种情况:
(1)array[mid] > array[high]:
出现这种情况的array类似[3,4,5,6,0,1,2],此时最小数字一定在mid的右边。
low = mid + 1
(2)array[mid] == array[high]:
出现这种情况的array类似 [1,0,1,1,1] 或者[1,1,1,0,1],此时最小数字不好判断在mid左边
还是右边,这时只好一个一个试 ,
high = high - 1
(3)array[mid] < array[high]:
出现这种情况的array类似[2,2,3,4,5,6,6],此时最小数字一定就是array[mid]或者在mid的左
边。因为右边必然都是递增的。
high = mid
注意这里有个坑:如果待查询的范围最后只剩两个数,那么mid 一定会指向下标靠前的数字
比如 array = [4,6]
array[low] = 4 ;array[mid] = 4 ; array[high] = 6 ;
如果high = mid - 1,就会产生错误, 因此high = mid
但情形(1)中low = mid + 1就不会错误

# -*- coding:utf-8 -*-
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        # write code here
        if len(rotateArray)==0:
            return 0
        l = 0
        r = len(rotateArray)-1
        while(l<r):
            mid = l + (r-l)/2
            if rotateArray[mid] > rotateArray[r]:
                l = mid + 1
            elif rotateArray[mid] == rotateArray[r]:
                r = r -1
            else:
                r = mid
        return  rotateArray[l]
            

7. 斐波那契数列

题目描述
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
n<=39

# -*- coding:utf-8 -*-
class Solution:
    def Fibonacci(self, n):
        # write code here
        if n==0:
            return 0
        if n==1:
            return 1
        f0 = 0
        f1 = 1
        for i in range(n-1):
            f = f0 + f1
            f0 = f1
            f1 = f 
        return f

8 .跳台阶

题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

# -*- coding:utf-8 -*-
class Solution:
    def jumpFloor(self, number):
        # write code here
        #f1 = 1 f2 = 2 
        if number == 0:
            return 0
        if number == 1:
            return 1
        f0 = 0 
        f1 = 1
        for i in range(number):
            f = f0 + f1
            f0 = f1
            f1 = f
        return f 

9. 变态跳台阶

题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

# -*- coding:utf-8 -*-
class Solution:
    def jumpFloorII(self, number):
        # write code here
        #f0 = 0 f1 = 1 f2 = 2 f3 = 4
        if number == 0:
            return 0
        res = 1
        for i in range(number-1):
            res *=2
        return res 

10. 矩形覆盖

题目描述
我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
在这里插入图片描述

# -*- coding:utf-8 -*-
class Solution:
    def rectCover(self, number):
        # write code here
        #f1 = 1 f2 =2 f3 = 3
        if number == 0:
            return 0
        if number == 1:
            return 1
        f0 = 0 
        f1 = 1
        for i in range(number):
            f = f0 + f1
            f0 = f1
            f1 = f
        return f 

11. 二进制中1的个数

题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
http://www.cnblogs.com/cotyb/p/5186461.html
0xffffffff = 1111 1111 1111 1111 1111 1111 1111 1111 (8个F的二进制形式, 一个F占4个字节 )
0x代表16进制,后面是数字

解法一

在python中,负数和0xffffffff按位与之后变成一个无符号数,二进制表示为编码形式
bin() 返回一个整数 int 或者长整数 long int 的二进制表示。
# -*- coding:utf-8 -*-
class Solution:
    def NumberOf1(self, n):
        nbin = bin(n & 0xffffffff)
        return nbin.count('1')

解法二

把一个整数减去1之后再和原来的整数做按位与,得到的结果相当于是把整数的二进制表示中最右边的一个1变成0
# -*- coding:utf-8 -*-
class Solution:
    def NumberOf1(self, n):
        if n < 0:
            n = n & 0xffffffff #4bit
        cnt = 0
        while n:
            n &= n-1
            cnt += 1
        return cnt

12. 数值的整数次方

题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

Python 条件表达式语法为: X if C else Y,假如条件C成立,返回X,如果条件C不成立,返回Y。

*快速幂时间复杂度O(logn)

11的二进制是1011
11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1。因此,我们将a¹¹转化为算
在这里插入图片描述

# -*- coding:utf-8 -*-
class Solution:
    def Power(self, base, exponent):
        p = abs(exponent)
        res = 1.0
        while(p):
            if (p&1):    #与运算判断为奇数 比%运算快
                res *= base
            base *= base
            p >>= 1      #右移代替 除2
        return res if exponent>0 else 1/res 
        #return base**exponent  #python中幂运算**   -返回x的y次幂

13 调整数组顺序使奇数位于偶数前面

题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

# -*- coding:utf-8 -*-
class Solution:
    def reOrderArray(self, array):
        l = []
        r = []
        for i in array:
            if  i&1:
                l.append(i)
            else:
                r.append(i)
        #l.extend(r)
        #return l
        return l+r  #list+ 和extend一样,是+号生成的是一个新的对象,而extend则是在原地的修改l。
        

14 . 链表中倒数第k个结点

题目描述
输入一个链表,输出该链表中倒数第k个结点。
倒数第k个点和最后一个点的距离是k-1
注意 k可能大于链表长

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def FindKthToTail(self, head, k):
        if head==None or k<=0:
            return None
        slow = head
        fast = head
        while(k-1):  #先走 k-1 步
            if fast.next:
                fast = fast.next
            else:
                return None
            k -= 1
        while(fast.next):
            fast = fast.next
            slow = slow.next
        return slow

15.反转链表

题目描述
输入一个链表,反转链表后,输出新链表的表头。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        pre = None
        while(pHead):
            pnext = pHead.next #保存next 防止断链
            pHead.next = pre
            pre = pHead
            pHead = pnext
        return pre  #最后一个节点是头结点
            

16.合并两个排序的链表

题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回合并后列表
    def Merge(self, pHead1, pHead2):
        if (pHead1==None):
            return pHead2
        if (pHead2==None):
            return pHead1
        if (pHead1.val < pHead2.val):
            res = pHead1
            res.next = self.Merge(pHead1.next, pHead2)
        else:
            res = pHead2
            res.next = self.Merge(pHead1, pHead2.next)
        return res

17 树的子结构

题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def HasSubtree(self, pRoot1, pRoot2):
        res = False
        root1 = pRoot1
        root2 = pRoot2
        if (root1 and root2):#当Tree1和Tree2都不为空的时候,才进行比较。否则直接返回false
            if (root1.val==root2.val):
                res = self.DoesTreeHave(root1, root2)#以这个根节点为为起点判断是否包含Tree2
            if (not res):
                res = self.HasSubtree(root1.left, root2)#如果找不到,那么就再去root的左儿子当作起点,去判断时候包含Tree2
            if (not res):
                res = self.HasSubtree(root1.right, root2)
        return res
    def  DoesTreeHave(self , root1, root2):
        if (root2==None):#如果Tree2已经遍历完了都能对应的上,返回true
            return True
        if (root1== None): #如果Tree2还没有遍历完,Tree1却遍历完了。返回false
            return False
        if(root1.val!=root2.val):#如果其中有一个点没有对应上,返回false
            return False
        return self.DoesTreeHave(root1.left, root2.left) and  self.DoesTreeHave(root1.right, root2.right)
        #如果根节点对应的上,那么就分别去子节点里面匹配

18 二叉树的镜像

题目描述
操作给定的二叉树,将其变换为源二叉树的镜像。
输入描述:
二叉树的镜像定义:源二叉树

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回镜像树的根节点
    def Mirror(self, root):
        if not root:
            return 
        tmp = root.left
        root.left = root.right
        root.right = tmp
        self.Mirror(root.left)
        self.Mirror(root.right)
        return root

19. 顺时针打印矩阵

题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

# -*- coding:utf-8 -*-
class Solution:
    # matrix类型为二维列表,需要返回列表
    def printMatrix(self, matrix):
        # write code here
        row = len(matrix)
        col = len(matrix[0])
        up = 0
        down = row -1
        left = 0 
        right = col -1
        res =[]
        while(up <= down and left <= right):
            for i in range(left,right+1):
                res.append(matrix[up][i])
            up += 1
            for i in range(up, down+1):
                res.append(matrix[i][right])
            right -= 1
            if (up <= down):  #之前的up 增加需要再判断防止重复输出
                for i in range(right, left-1,-1):
                    res.append(matrix[down][i])
            down -= 1
            if (left <= right):
                for i in range(down, up-1,-1):
                    res.append(matrix[i][left])
            left += 1
        return res

20. 包含min函数的栈

题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。

# -*- coding:utf-8 -*-
class Solution:
    def __init__(self):
        self.s1 = [] #数据栈
        self.s2 = [] #辅助栈 每次都把最小的元素押入
    def push(self, node):
        self.s1.append(node)
        if not self.s2:         #空栈直接押入
            self.s2.append(node)
        else:
            if node < self.s2[-1]:  
                self.s2.append(node)
            else:
                self.s2.append(self.s2[-1])
    def pop(self):    #出栈 同步
        self.s2.pop()
        self.s1.pop()
    def top(self):
        return self.s1[-1]
    def min(self):
        return self.s2[-1]

21 .栈的压入、弹出序列

题目描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

# -*- coding:utf-8 -*-
class Solution:
    def IsPopOrder(self, pushV, popV):
        if not pushV:
            return False
        s = []
        j = 0
        for i in pushV:
            s.append(i)
            while(s and s[-1]==popV[j]):
                s.pop()
                j += 1
        return False if s else True    
             

22. 从上往下打印二叉树

题目描述
从上往下打印出二叉树的每个节点,同层节点从左至右打印。

树的层次遍历 用队列实现
# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回从上到下每个节点值列表,例:[1,2,3]
    def PrintFromTopToBottom(self, root):
        if not root: 
            return []  #返回空的list
        q = []         #队列q 用list 
        q.append(root)
        res = []
        while(q):
            i = q[0]       #队头
            res.append(i.val)
            if i.left:
                q.append(i.left)
            if i.right:
                q.append(i.right)
            q.pop(0)
        return res 
                

23.二叉搜索树的后序遍历序列

题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

# -*- coding:utf-8 -*-
class Solution:
    def VerifySquenceOfBST(self, sequence):
        if sequence==None or len(sequence)==0:
            return False
        length=len(sequence)
        root=sequence[length-1]
        # 在二叉搜索 树中 左子树节点小于根节点
        for i in range(length):
            if sequence[i]>root:
                break
        # 二叉搜索树中右子树的节点都大于根节点
        for j  in range(i,length):
            if sequence[j]<root:
                return False
        # 判断左子树是否为二叉树
        left=True
        right=True
        if  i>0:
            left=self.VerifySquenceOfBST(sequence[0:i])
        # 判断 右子树是否为二叉树
        if i<length-1:
            right=self.VerifySquenceOfBST(sequence[i:length-1])
        return left and right

24. 二叉树中和为某一值的路径

25. 复杂链表的复制

26.二叉搜索树与双向链表

27.字符串的排列

全排列 递归

题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。

# -*- coding:utf-8 -*-
class Solution:
    def Permutation(self, ss):
        if not ss:
            return []
        if len(ss) == 1:
            return [ss]
        ret = []
        #遍历字符串,固定第一个元素,然后递归求解
        for i in range(len(ss)):
            for j in  self.Permutation(ss[:i]+ss[i+1:])
                ret.append(ss[i]+j)
        #通过set进行去重,sorted进行重新排序
        return sorted(list(set(ret)))

28. 数组中出现次数超过一半的数字

题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

方法一 哈希

# -*- coding:utf-8 -*-
class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        d = {}
        for i  in numbers:
            if i not in d:
                d[i] = 1
            else:
                d[i] += 1
        for k,v in d.items():
            if v > len(numbers)/2:
                return k
        return 0

方法二 利用快排思想

class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        if not numbers:
            return False
        le =  len(numbers) 
        mid = le >> 1
        l = 0
        r = le-1
        ind = self.partition(numbers,l,r)
        while(ind != mid):
            if ind < mid:
                ind = self.partition(numbers,ind+1,r)
            if ind > mid:
                ind = self.partition(numbers,l,ind-1)
        cnt = 0
        res = numbers[mid]
        for i in numbers:
            if i == res:
                cnt += 1
        return res if cnt*2>le else 0
    
    def partition(self,a, l, r):
        x = a[l]
        while(l<r):
            while(a[r]>=x and l<r):
                r -= 1
            a[l], a[r] = a[r],a[l]
            while(a[l]<=x and l<r):
                l += 1
            a[l], a[r] = a[r],a[l]
        a[l] = x
        return l
    
    '''
    def partition(self,a, l, r):
        x = a[r]
        j = l 
        for i in range(l,r):
            if a[i] <= x:
                a[i],a[j] = a[j],a[i]
                j += 1
        a[j],a[r] = a[r], a[j]
        return j
    '''

方法三 打擂法

# -*- coding:utf-8 -*-
class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        if not numbers:
            return 0
        cnt = 1
        res = numbers[0]
        for i in range(1,len(numbers)):
            if cnt == 0:
                res = numbers[i]
                cnt = 1
            else:
                if numbers[i] == res:
                    cnt += 1
                else:
                    cnt -= 1
        cnt = 0
        for i in numbers:
            if i == res:
                cnt += 1
        return res if cnt*2 > len(numbers)else 0

29. 最小的K个数

题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

方法一、快排思想 O(n)

# -*- coding:utf-8 -*-
class Solution:
    def GetLeastNumbers_Solution(self, tinput, k):
        if not tinput or k <=0 or k>len(tinput):
            return []
        ind = self.partition(tinput, 0, len(tinput)-1)
        while(ind != k-1):
            if ind < k-1 :
                ind = self.partition(tinput, ind+1, len(tinput)-1)
            if ind > k-1 :
                ind = self.partition(tinput, 0, ind-1)
        return sorted(tinput[:k])
    def partition(self, a,l,r):
        x = a[r]
        j = l 
        for i in range(l,r):
            if a[i] < x:
                a[i], a[j] = a[j],a[i]
                j += 1
        a[j],a[r] = a[r],a[j]
        return j

方法二、 大顶堆 heapq 模块 O(nlogk)

# -*- coding:utf-8 -*-
import heapq
class Solution:
    def GetLeastNumbers_Solution(self, tinput, k):
        if not tinput or k<=0 or k>len(tinput):
            return []
        h = [] #堆
        for i in tinput[:k]:
            heapq.heappush(h, -i)  #大顶堆
        for i in tinput[k:]:
            htop = -h[0] #堆顶元素
            if i < htop:
                heapq.heapreplace(h, -i)
        h = [-i for i in h]
        return sorted(h)

heapq.nsmallest

https://github.com/qiwsir/algorithm/blob/master/heapq.md

# -*- coding:utf-8 -*-
import heapq
class Solution:
    def GetLeastNumbers_Solution(self, tinput, k):
        if not tinput or k<=0 or k>len(tinput):
            return []
        return heapq.nsmallest(k, tinput, key=None)

30. 连续子数组的最大和

题目描述
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)

方法一

# -*- coding:utf-8 -*-
class Solution:
    def FindGreatestSumOfSubArray(self, array):
        cursum = 0
        ma = array[0]
        for i in array:
            if cursum <= 0:
                cursum = i
            else:
                cursum += i
            ma = max(ma, cursum)
        return ma

方法二、 动态规划 递归公式 dp[i] = max(arr[i] , dp[i-1]+arr[i])

# -*- coding:utf-8 -*-
class Solution:
    def FindGreatestSumOfSubArray(self, array):
        cursum = 0
        ma = array[0]
        for i in array:
            cursum = max(cursum+i,i)
            ma = max(ma, cursum)
        return ma

31. 整数中1出现的次数(从1到n整数中1出现的次数)

32. 把数组排成最小的数

题目描述
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

# -*- coding:utf-8 -*-
class Solution:
    def PrintMinNumber(self, numbers):
        if not numbers: return ""
        s = map(str, numbers)
        s = sorted(s, cmp=lambda x,y:cmp(x+y,y+x))
        return "".join(s).lstrip('0') or 0 #去除前导0,全为0时输出0

33.丑数

34. 第一个只出现一次的字符

题目描述
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).

# -*- coding:utf-8 -*-
class Solution:
    def FirstNotRepeatingChar(self, s):
        if not s: return -1
        d = {}
        for i in s:
            if i not in d:
                d[i] = 1
            else:
                d[i] += 1
        for i in range(len(s)):
            if d[s[i]] ==1:
                return i
        return -1 

35 数组中的逆序对

36 两个链表的第一个公共结点

题目描述
输入两个链表,找出它们的第一个公共结点。
思路一:两条相交的链表呈Y型。可以从两条链表尾部同时出发,最后一个相同的结点就是链表的第一个相同的结点。可以利用栈来实现。时间复杂度有O(m + n), 空间复杂度为O(m + n)

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        stack1 = []
        stack2 = []
        while(pHead1):
            stack1.append(pHead1)
            pHead1 = pHead1.next
        while(pHead2):
            stack2.append(pHead2)
            pHead2 = pHead2.next
        first = None
        while stack1 and stack2:
            top1 = stack1.pop()
            top2 = stack2.pop()
            if top1 == top2:
                first = top1
            else:
                break
        return first

思路二:
思路一其实利用栈主要解决就是同时到达第一个结点的问题。那么从链表头出发如何同时到达第一个相同的结点呢? 链表的长度相同就可以,其实就是走的结点数目相同。所以可以让其中长的链表先走几步,剩余的长度到短链表的长度相同。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        p1 = pHead1    #统计完长度指针就指向了末尾
        p2 = pHead2
        if not p1 or not p2: return None 
        len1 = 0
        len2 = 0
        while(p1):
            p1 = p1.next
            len1 += 1
        while(p2):
            p2 = p2.next
            len2 += 1
        if len1>len2:
            while(len1-len2):
                pHead1 = pHead1.next
                len1 -= 1
        else:
            while(len2 -len1):
                pHead2 = pHead2.next
                len2 -= 1
        while(pHead2 and pHead1):
            if pHead2 == pHead1:
                return pHead1
            pHead1 = pHead1.next
            pHead2 = pHead2.next
        return None

37 数字在排序数组中出现的次数

题目描述
统计一个数字在排序数组中出现的次数。

# -*- coding:utf-8 -*-
class Solution:
    def GetNumberOfK(self, data, k):
        if not data: return 0
        cnt = 0
        l = 0
        r = len(data) - 1
        while(l<=r):
            mid = (l+r)/2
            if data[mid]> k:
                r = mid -1
            if data[mid] < k:
                l = mid +1
            ## 这个数字前面后面都可能存在我们要找的数
            if data[mid] == k:
                while(mid >=0 and data[mid]==k):
                    mid -= 1
                mid += 1
                while(mid <=len(data)-1 and data[mid]== k):
                    mid += 1
                    cnt += 1
                return cnt          #要返回,不然一直循环       
        return 0

38 二叉树的深度

题目描述
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def TreeDepth(self, pRoot):
        if not pRoot: return 0
        return max(self.TreeDepth(pRoot.left),self.TreeDepth(pRoot.right)) +1 

39 .平衡二叉树

题目描述
输入一棵二叉树,判断该二叉树是否是平衡二叉树。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值