【问题标题】:Is python really slow or is it because I havent optimized the python code?python真的很慢还是因为我没有优化python代码?
【发布时间】:2021-10-30 22:53:00
【问题描述】:

Leetcode 的问题是:给定一个字符串 s,求最长不重复字符的子串的长度。

https://leetcode.com/problems/longest-substring-without-repeating-characters/

我在 C++ 和 Python 中都进行了编码,看看是否存在巨大的性能差距,结果是:

以下是相同逻辑的c++和python实现:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int max_count=0;
        int k=1;
        int i=0;
        int j=0;
        bool visited[256];
        memset(visited,false,256);
        int n=s.size();
        
        while(k<=n && i<n && j<n){
            /*for(int l=i;l<=j;l++) cout << s[l];
            cout << endl;*/
            
            if(visited[int(s[j])]){
                memset(visited,false,256);
                k=1;
                i++;
                j=i+k-1;
            }else{
                if (max_count<k) max_count=k;
                visited[int(s[j])]=true;
                k++;
                j++;
            }
        }
        return max_count;
    }
};

class Solution:
    def lengthOfLongestSubstring(self, a: str) -> int:
        
        #apply sliding window for k=0,1,2,..,n until repetition is found for a substring
        k=1 #wndow length
        i=0 #starting indx of substring
        j=0 #ending indx of substring
        init_visited=[False]*256
        visited=init_visited[:]
        max_count=0
        n=len(a)
        
        while k<=n and j<n and i<n:       
            #print(k,i,j)
            #print(a[i:j+1])
            if visited[ord(a[j])]:
                visited = init_visited[:]
                i+=1
                k=1
                j=i+k-1
            else:
                visited[ord(a[j])]=True
                max_count=max(max_count,k)
                
                k+=1
                j+=1
        
        return max_count

我可以对 Python 代码进行哪些改进以使其更快?

【问题讨论】:

  • 愤世嫉俗的回答:python真的很慢吗?是的。你的代码没有优化吗?是的。
  • 如果你的问题在 codereview.stackexchange.com 上被问到,它可能会吸引更多有见地的答案,特别是关于提交有效的代码并要求任何改进
  • memset(visited,false,256) 很可能是错误的; sizeof(bool) 通常不是 1。
  • 如果算上编译 C++ 代码所花费的时间,我敢打赌 Python 版本会更快 ;-)
  • 您的算法是 O(n^2),因为它会查看所有子字符串。可以在 O(n) 中解决这个问题,只需对输入进行一次传递。

标签: python c++ algorithm performance


【解决方案1】:

Python 永远不会像 C++ 那样快,但您可以使用字典来优化这个函数:

def longestsub(S):
    distinct = set()
    result   = 0
    start    = 0
    for i,c in enumerate(S):
        if c in distinct:
            result = max(result,i-start)
            distinct.difference_update(S[start:i])
            start  = i
        distinct.add(c)
    result = max(result,len(S)-start)
    return result

输出:

testData = ["abcabcbb","bbbbb","pwwkew",""]
for s in testData:
    print(f"'{s}' : ",longestsub(s))

'abcabcbb' :  3
'bbbbb' :  1
'pwwkew' :  3
'' :  0

性能:

longestsub("abcabcbb"*10000) # 80,000 characters --> 3 in 30 ms

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多