美文网首页
剑指offer--algorithm

剑指offer--algorithm

作者: strive鱼 | 来源:发表于2018-04-11 23:11 被阅读0次

眼勤、手勤、脚勤 ,方成大事--了不起的匠人第三季年画
智者,上善若水,海纳百川,仁者,高山仰止,厚德载物--了不起的匠人第三季年画

题三--替换空格

we are happy   输出  we%20are%20happy

上述题目的一些说明:

image.png

下面开始解题:
该题的解题关键在于是在原来的字符串上修改,还是创建新的字符串在新的字符串上做修改,如果在原来字符串上作修改,就必须使得空格后的每个字符向后移动两个字节,否则会被覆盖,如果创建新的字符串,则不存在该问题,可以创建足够多的内存

  • O(n2)时间复杂度思路--正向思路:简单来讲,碰到一个空格,就把空格后面的部分后移,该例子中有两个空格,可以发现,“happy" 移动了两次,时间复杂度为O(n2),该思路为从前往后移动的思路
  • O(n1)时间复杂度思路--逆向思路: 逆向思维,简单来讲就是先计算好将空格替换后的字符串的长度,然后设定两个指针,一个指向替换之前的字符串的末尾,另一个指向替换后字符串的末尾,这样一来,每一个原先的字符都只移动一次,时间复杂度问为O(n1),该思路本质是一个从后往前的思路,因此较思路1更具优势

其中,关于O(n1)思路,书中已经说的非常完美,只能盗用膜拜


image.png

下面为代码:

方法一:该方法实际上是创建了一个新的字符串,占用了新的内存,看似十分简单,但不是最佳选择
class method1(object):
    def __init__(self,s):
        self.s=s
    def replace1(self):
        l=[]
        sl=list(self.s)#将字符串转化为列表,即拆分为['w','e',' ',.....]
        for item in sl:
            if item==' ':#如果为空格
                l.append('%20')
            else:
                l.append(item)
        return ''.join(l)#利用Join方法把内容穿起来

def main():
    s='we are happy'
    m=method1(s)
    print (m.replace1())
    
if __name__=='__main__':
    main()
方法二:最狗血,但是这肯定不是本题的意义所在
class method2(object):
    def __init__(self,s):
        self.s=s
    def replace2(self):
        return self.s.replace(' ','%20')

def main():
    s='we are happy'
    m=method2(s)
    print (m.replace2())
    
if __name__=='__main__':
    main()
方法三:书中的 O(n1)思路,本题的意义所在
class method3(object):
    def __init__(self,s):
        self.s=s
    def news(self):#用来计算新的空格的长度
        sl=list(self.s)
        l=len(self.s)#原先字符串的长度
        count=0#用来计算空格的个数
        for item in sl:
            if item==' ':
                count+=1
        l=l+count*2
        return l
    def replace3(self,l):#l为上述的news方法得到的
        newl=int(l)*[None]#生成一个全为None 的列表
        indexoriginal=len(self.s)-1#即将指针放在源字符串的最后一个字母位置
        indexnew=int(l)-1#将另一个指针放在新生成的字符串长度的最后一个字节
        while indexnew>=0 and indexnew>=indexoriginal:#进行判断
            if self.s[indexoriginal]==' ':
                newl[indexnew-2:indexnew+1]=['%','2','0']#就将空格的替代符号依次插入到新的空列表中
                indexoriginal-=1#更新指针的位置,上前挪动一个字节位
                indexnew-=3#同样另一个指针向前挪动三个字节位
            else:
                newl[indexnew]=self.s[indexoriginal]#如果判断不是空格的话,就将原先的字母传递给新生成的列表,进行存储
                indexoriginal-=1#指针向前移动一位
                indexnew-=1#紧跟上一个指针向前移动,目的是找到插入%20的位置
        return ''.join(newl)#最后粘合该序列
                
        
        
    
def main():
    s='we are happy'
    m=method3(s)
    l=m.news()
    print (m.replace3(l))
    
    

if __name__=='__main__':
    main()

至次该题解答完毕,上述代码亲写有效

题四--从尾到头打印列表

输入一个链表的头节点,从尾到头反过来打印每一个节点的值

下面开始解题:

  • 思路一:就是先改变指针的方向,然后得到一个原来链表的反向链表,然后逐一地从头获得链表的内容-----但是该方法正如书中所说改变了题目原先的链表结构
  • 思路二:就是不改变原先链表的结构,先遍历到的数据后输出(pop),后遍历到的数据先输出,有没有很熟悉这个概念----对,正是栈的基本原理

在进行代码编写之前,还是必须把链表结构搞清楚,常见的链表构造和基本操作如下代码:

#单项列表它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。

class node(object):
    def __init__(self,item):
        """
        单项列表的节点构造(一个信息域,一个链接域)
        """
        self.item=item
        self.next=None
    def getitem(self):
        return self.item
    def getnext(self):
        return self.next#本质上把它理解为跳到下一个节点
    def setitem(self,newitem):
        self.item=newitem
    def setnext(self,newnext):
        self.next=newnext#增加一个新节点

class singlelinklist(object):
    def __init__(self):
        self.head=None#定义了表头
        self.size=0
    def is_empty(self):
        return self.head==None#判断表头是否为空,这是一个布尔型的返回值
    def add(self,item):#添加节点,实现相互链接
        temp=node(item)#实例化
        temp.setnext(self.head)#更改其原先的指针
        self.head=temp#自己变为了表头,且表头指向None
        #return temp
    def append(self,item):#在链表的尾部添加元素
        temp=node(item)#首先实例化一个要添加的节点
        if self.is_empty():#如果表头为空,就在这个位置上添加
            self.head=temp#就把这个新元素作为表头
        else:
            current=self.head
            while current!=None:
                current=current.getnext()#此时往下移动一个节点,下一个节点变为表头
            current.setnext(temp)#把这个节点加入到末尾,它自己temp本身也是指向None
    def search(self,item):#检查元素是否在队列里面
        current=self.head#将表头实例化
        verify=False#用于flag,判断要搜寻的元素是否在所有的节点里面
        while current!=None and not verify:
            if current.getitem()==item:
                 verify=True
            else:
                current=current.getnext()#移动到下一个节点
            return verify
    def index(self,item):#输出所搜索的元素的索引的位置
        current=self.head
        count=0
        verify=False
        while current!=None and not verify:
            count+=1
            if current.getitem()==item:
                verify=True
            else:
                current=current.getnext()
            if verify:
                return count 
            else:
                return 'item not in this singlelinklist'
    def remove(self,item):#从队列中删除一个数值
        current=self.head
        prone=None
        while current!=None:
            if current.getitem()==item:
                if not prone:
                    self.head=current.getnext()
                else:
                    prone.setnext(current.getnext())
                break
            else:
                current=current.getnext()
                prone=current
            
    def insert(self,pos,item):#第一个参数是要插入的索引值
        if pos<=1:
            self.add(item)#就将其插入在最前边
        if pos>self.size:
            self.append(item)
        else:
            temp=node(item)#先把其狗造成节点
            count=1
            pre=None
            current=self.head
            while pos>count:
                count+=1
                pre=current#先将原来的表头进行复制
                current=current.getnext()#跳到表头的下一个节点
            pre.setnext(temp)#插入新的节点
            temp.setnext(current.getnext())#使该节点与后续的节点再链接起来
                
                
        
    
        
        
def main():
    demo=singlelinklist()
    demo.add(2)
    demo.add(3)
    print (demo)
    
if __name__=='__main__':
    main()

明白了上述的代码,链表的代码写法根据每个人的理解,也会有所不同,这道题的解答代码如下,尝试采用不同的方式:

class node(object):
   def __init__(self,element=None):
       self.element=element
       self.next=None #指向None 

"""
实现一个单链表的链接
"""       
n1=node(1)
n2=node(2)
n3=node(3)
n4=node(4)
n1.next=n2
n2.next=n3
n3.next=n4
      
def log(node):#日志打印,这样就可以清楚的看到链表的结构
    while node is not None:
        print ('element', node.element)
        node=node.next#实现层层嵌套打印,很巧妙
        
class peek(object):#栈的结构
    def __init__(self):
        self.head=node()#声明一个表头节点
    def push(self,element):#进栈
        n=node(element)#声明一个实例
        n.next=self.head.next
        self.head.next=n#至此就将表头与新的节点串联起来,没有返回值
    def pop(self):#出栈,先入的后出
        n=self.head.next
        self.head.next=n.next
        return n.element
        
  


def main():
    #log(n1)可打印出所有的链表结构
    p=peek()
    p.push('a')
    p.push('b')
    p.push('c')
    """
    链表的结构为c--b--a,而非a--b--c,请格外注意,这是栈结构不同于
    链表结构的特点
    """
    print (p.pop())
    print (p.pop())
    print (p.pop())
    """
    打印结果为
    c
    b
    a
    """

    
    
if __name__=='__main__':
    main()
  • 不过分追求外在的十五,而追寻内心的力量---了不起的匠人紫砂壶
  • 劝成殆事,美成在久,知世事之艰,仍定心磨练自我,即仰宇宙之大,也怀有日用器皿之心
  • 欣于所遇,快然自足,繁华在心,安宁也心

晚安

相关文章

  • 剑指offer--algorithm

    眼勤、手勤、脚勤 ,方成大事--了不起的匠人第三季年画智者,上善若水,海纳百川,仁者,高山仰止,厚德载物--了不起...

  • 剑指

    遥望中原九点烟,风云直上七重天。 今朝再向江湖去,一剑流星谁比肩? 2011.10(1488)

  • 剑指

    1. 二维数组中查找 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照...

  • 全网最全剑指offer题目解答

    【剑指offer】Java版代码(完整版) 【剑指offer】1-10题 【剑指offer】11-20题 【剑指o...

  • 剑指offer

    第一题:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,...

  • 剑指BAT

    Android工作5年半了,一毕业就开始做这行。在现在这家公司工作了3年整,最近有换工作的打算,所以在猎聘...

  • 《剑指offer》

    4.调整数组顺序使奇数位于偶数前面 题目描述:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇...

  • 气剑指

    “聚气于指尖,凝其成剑,利可断金。”牢头对身边的狱卒说。 只见牢头举起的右手指尖逐渐变红,转而变白,隐隐发出音量很...

  • 剑指offer

    二维数组中查找数在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到...

  • 剑指苍穹

    逆天命,斩苍穹,吾乃修士,率性而为!《剑指苍穹》是一款逍遥仙侠MMORPG——群魔阻道,斩群魔;妖邪拦路,诛妖邪,...

网友评论

      本文标题:剑指offer--algorithm

      本文链接:https://www.haomeiwen.com/subject/lekzhftx.html