python 深copy 浅copy 解释+Palindrome Partitioning例子

先给出一个例题:

也可以先看后面给出的小鸡例子

Given a string s, partition s such that every substring of the partition is a palindrome.

Return all possible palindrome partitioning of s.

Input: "aab"
Output:
[
  ["aa","b"],
  ["a","a","b"]
]

解题思路:先要判断子串是否是回文,然后使用dfs遍历即可

Palindrome的作用是判断输入字符串是否是回文数

flagPalindrome就是标示,如果flagPalindrome[i][j]=1,那么就是说s字符串从i到j位置这一子串是回文数,如果是0那么就不是回文数。

dfs就是遍历得到所有情况,注意


res = temp[:]
res.append(s[start:i+1])
self.dfs(s,i+1,res)

#上面两句不可简写为如下:
temp.append(s[start:i+1])
self.dfs(s,i+1,temp)

因为这里涉及到python的深浅拷贝,如果简写为下面两句话时,那么就是深拷贝(实际上是地址绑定,当母体发生改变时,复制它的那个变量的值也会发生相应的改变),结果就是错的:

笔者这里试了一下会输出:

[  ["a","a","b"] , ["a","a","b","aa","b"]]

一般对于dfs来说比如:

比如我们在上面进行dfs,用一个列表存储列表,开始肯定是1-4-10,此时列表是[1,4,10],然后进行第一次回溯到4,当前列表按理说应该是[1,4]但是当是深拷贝时,列表实际上可以看成是一个全局变量了!会回溯到上步的4,但是上步对应的列表已经被改变啦!正常来说这一步就是这一步的,不应该受下一步的影响,但是由于深拷贝的原因,这里受了影响。

对应到本题如果只是使用temp那么在第一次结束后即["a","a","b"]后,在进行for的下一次循环时,回溯到temp最开始的时候,按理说,这时temp还没有进行任何的append (回溯的过程可以看出就是去掉append的那些步骤),temp就是[] 但由于此时temp实际上已经是["a","a","b"]了,

因为由于深拷贝的原因,它依然悄悄的变为全局变量,后面的每一步其实都在影响改变着当前的temp,所以回溯回来的时候,temp已经不是当初的temp啦!

怎么办呢?当然再令一个临时res,其和temp是两个不同的东西(如果写成res=temp这相当于还是深拷贝,还会得出和上面一样的错误结果),res只是复制了一下temp的值,而并没有像深拷贝那样两者进行了地址绑定。那么此时的res就是[],不管后面temp怎么变化,res的值依然是[]

同样

self.result.append(temp[:])

#不要写成
self.result.append(temp)

如果还是没有懂,笔者再举个不太恰当的例子:

比如一只小鸡从家里出发去外面的世界闯荡,临走时鸡妈妈对她的影响值量化为是A,小鸡先去了北京闯荡了5年,学到不少本领,又去上海闯荡了3年,又学到不少本领,客观上此时的小鸡给人的影响值已经量化为B啦,此时小鸡回家(回缩)从上海北京,从北京到家里,那妈妈的影响值是多少呢?应该还是A,这也是我们使用dfs想看到的结果。

但如果小鸡在闯荡期间,把所见所闻都通过打电话告诉了妈妈,那么其实在妈妈眼里,对孩子的影响值一直都在随着小鸡去不同城市打拼经历变化而变化,当小鸡回溯到家里的时候妈妈对其影响值应该也变为了B,但这不是我们想要的,怎么办呢?

上面我们通过一个res进行了浅拷贝,意思就是说当初小鸡离开的时候妈妈对她的影响值量化为是A,妈妈当场又把这一影响告诉了兔帅哥,尽管以后小鸡和妈妈通电话,妈妈的影响值会改变,但是当小鸡回溯回来时兔帅哥对小鸡的影响依然是A,所以我们此时用兔帅哥的影响值就可以了!对应到程序时就是说我们在递归时用res,而不用temp

最后是完整代码:

class Solution:
    def partition(self, s):
        """
        :type s: str
        :rtype: List[List[str]]
        """
        self.flag =[[0 for i in range(len(s))] for j in range(len(s))]
        self.result = []
        
        self.flagPalindrome(s)
        self.dfs(s,0,[])
        return self.result
        
    def Palindrome(self,s):
        if s==s[::-1]:
            return True
        else:
            return False
        
    def flagPalindrome(self,s):
        for i in range(len(s)):
            for j in range(i+1,len(s)+1):
                if self.Palindrome(s[i:j]):
                    self.flag[i][j-1] = 1
                    self.flag[j-1][i] = 1
                    
    def dfs(self,s,start,temp):
        if start == len(s):
            self.result.append(temp[:])
            return
        for i in range(start,len(s)):
            if self.flag[start][i]==1:
                res = temp[:]
                res.append(s[start:i+1])
                self.dfs(s,i+1,res)

猜你喜欢

转载自blog.csdn.net/weixin_42001089/article/details/83017978
今日推荐