python 算法回顾(1) 变位词 和 timeit模块

工作的时候感觉思路没有以前那么灵活了。 决定没事的时候多做点算法题

python 时间复杂度,官方参考文档

https://wiki.python.org/moin/TimeComplexity

 

# 判断两次是不是变位词? 例如 heart 和 earth是变位词, 其中h的位置放到了最后

逐字检查(时间复杂度 O(n^2))

def judge(s1, s2):
    # 因为python的字符串是不可变类型,所以需要对s2转换
    # 如果s1能够在s2中找到对应的字符,那么把找到的字符置为None,表明已经找到
    s2 = list(s2)
    is_ok = True if len(s1) == len(s2) else False
    for s in s1:
        if is_ok:
            for i in range(len(s2)):
                if s == s2[i]:
                    s2[i] = None
                    break
            else:
                is_ok = False
        else:
            break
    return is_ok


def anagram_solution_1(s1, s2):
    alist = list(s2) #  复制到s2列表
    pos1 = 0
    still_ok = True
    while pos1 < len(s1) and still_ok:  # 循环s1的每一个字符
        pos2 = 0
        found = False
        while pos2 < len(alist) and not found:  # 在s2中逐个对比
            if s1[pos1] == alist[pos2]:
                found = True
            else:
                pos2 = pos2 + 1
        if found:
            alist[pos2] = None  # 找完了而且找到了, 打钩
        else:
            still_ok = False  # 找完了但是没找到, 失败, 不用再循环s1的每个字符
        pos1 = pos1 + 1
    return still_ok


if __name__ == '__main__':
    print(judge("earth", "heart"))
    print(anagram_solution_1("earth", "heart"))

排序检查 ( 时间复杂度 O(nlogn))

def anagram_solution_2(s1, s2):
    alist1 = list(s1)
    alist2 = list(s2)

    alist1.sort()
    alist2.sort()

    pos = 0
    is_matched = True
    while pos < len(alist1) and is_matched:
        if alist1[pos] == alist2[pos]:
            pos += 1
        else:
            is_matched = False
    return is_matched


if __name__ == '__main__':
    print(anagram_solution_2("earth", "heart"))

 计数比较

# 计数比较法: 字典
def anagram_solution_3(s1, s2):
    s1_dict = dict()
    s2_dict = dict()

    for s in s1:
        if s in s1_dict:
            s1_dict[s] += 1
        else:
            s1_dict[s] = 0
    for s in s2:
        if s in s2_dict:
            s2_dict[s] += 1
        else:
            s2_dict[s] = 0

    # 判断两个字典是否相同
    # a = {"a": 10 + 2, "b": 10}
    # b = {"a": 9 + 3, "b": 9 + 1}
    # is_equal = True if len(a) == len(b) else False
    # for a_key, a_value in a.items():
    #     if a_key not in b or b.get(a_key) != a_value:
    #         is_equal = False
    #         break

    # 判断两个字典是否相同,也可以直接用"=="判断
    # a = {"a": 10+2, "b": 10}
    # b = {"a": 9+3, "b": 9+1}
    # print(a == b)
    return s1_dict == s2_dict


# 计数比较: 列表
def anagram_solution_4(s1, s2):
    c1 = [0] * 26  # 计算26个字母的格式
    c2 = [0] * 26

    for s in s1:
        pos = ord(s) - ord('a')  # ord('a') 表示a的ascii码值, 这里ord('a')=97
        c1[pos] += 1
    for s in s2:
        pos = ord(s) - ord('a')
        c2[pos] += 1

    # 判断两个列表是不是相同
    # j = 0
    # still_ok = True
    # while j < 26 and still_ok:
    #     if c1[j] == c2[j]:
    #         j += 1
    #     else:
    #         still_ok = False
    # return still_ok

    # 判断两个列表是不是相同
    return c1 == c2


if __name__ == '__main__':
    print(anagram_solution_4("earth", "heart"))

# 生成前n个整数的列表

def test1():
    l = []
    for i in range(1000):
        l = l + [i]


def test2():
    l = []
    for i in range(1000):
        l.append(i)


def test3():
    l = [i for i in range(1000)]


def test4():
    l = list(range(1000))


from timeit import Timer
t1 = Timer("test1()", "from __main__ import test1")
print("concat %f seconds \n" % t1.timeit(number=1000))  # concat 0.962730 seconds

t2 = Timer("test2()", "from __main__ import test2")
print("concat %f seconds \n" % t2.timeit(number=1000))  # concat 0.143074 seconds

t3 = Timer("test3()", "from __main__ import test3")
print("concat %f seconds \n" % t3.timeit(number=1000))  # concat 0.082103 seconds

t4 = Timer("test4()", "from __main__ import test4")
print("concat %f seconds \n" % t4.timeit(number=1000))  # concat 0.010844 seconds 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值