首页 > 编程语言 >python | 算法大神左神(左程云)算法课程 第五节

python | 算法大神左神(左程云)算法课程 第五节

时间:2022-08-18 21:13:45浏览次数:80  
标签:index None python self 左神 next 算法 key ._

Today New -> python | 算法大神左神(左程云)算法课程 第五节(第几节我已经搞不清了,随便吧。。)

针对b站视频左神算法与数据结构,自己练习对应的python代码

相关链接:

1️⃣b站视频地址

2️⃣视频笔记(其实主要是题目截图)

⭐ 复制含有随机指针节点的链表

function 1 -> hash表

# 复制含有随机指针节点的链表
# 用hash表
class Node():
    def __init__(self, value=None, next=None, rand=None):
        self.value = value
        self.next = next
        self.rand = rand
def CopyList(head):
    hash = {} # key-value
    h = head
    while h is not None:
        hash[h] = Node(h.value) # key=old node; value=new node
        h = h.next
    h = head
    while h is not None:
        hash[h].next = h.next # new.next = old.next
        hash[h].rand = h.rand # new.rand = old.rand
        h = h.next
    return hash[head] # hash[old head] -> new head 

function 2 -> 不用hash表

难点:rand指针的随机性,如何找到复制的链表各个点的rand指针指定的位置?

先依附于原链表创建新节点,这样新表每个节点与原表各个节点之间就有一一对应位置,则根据原表的rand指针指定的位置就可以找到新表对应的位置,就可以先解决rand指针,再依次将新节点从原表中取下,同时连上next指针。

代码:

def CopyList2(head):
    if head is None: return None
    # step1 create new nodes
    h = head
    while h is not None:
        next = h.next # next -> save next node
        h.next = Node(h.value) # h.next -> new node
        h.next.next = next # new node -> next
        h = next # h move next
    # step2 rand part
    h = head
    while h is not None:
        next = h.next.next # next -> save next node of old list
        cur_copy = h.next # cur_copy -> new node
        cur_copy.rand = h.rand.next if h.rand is not None else None # find rand space or None
        h = next
    # step3 next part and split
    h = head
    res = head.next # new list head node
    while h is not None:
        next = h.next.next
        cur_copy = h.next
        cur_copy.next = next.next if next is not None else None # new list
        h.next = next # old list
        h = next
    return res

补充知识:Python中如何自己实现hash表?

参考链接 1

参考链接 2

自己动手实现,记录如下:

其中Array是存储结构

Slot是每一对key-value的记录结构

若干Slot构成一张HashTable

# Python中实现hash表结构

class Array(): # Array -> use to save hash table items
    def __init__(self, size=32, init=None):
        self._size = size
        self._items = [init] * size
        
    def __len__(self):
        return self._size
    
    def __getitem__(self, index):
        return self._items[index]
    
    def __setitem__(self, index, value):
        self._items[index] = value
        
    def clear(self, value=None):
        for i in range(len(self._items)):
            self._items[i] = value
            
    def __iter__(self):
        for item in self._items:
            yield item

class Slot(): # Slot -> save each key-value
    def __init__(self, key, value):
        self.key, self.value = key, value

class HashTable():
    Unused = None # Unused -> init (means an unused slot)
    Empty = Slot(None, None) # an empty slot
    
    def __init__(self):
        self._table = Array(size=8, init=HashTable.Unused)
        self.length = 0
        
    @property
    def _load_factor(self): # how much space has been used
        return self.length / float(len(self._table))
    
    def __len__(self): # num of not empty slot
        return self.length
    
    def _hash(self, key):
        return abs(hash(key)) % len(self._table)
    
    def _find_key(self, key):
        index = self._hash(key)
        _len = len(self._table)
        while self._table[index] is not HashTable.Unused: # an used slot
            if self._table[index] is HashTable.Empty: # this slot's key and value have been removed
                index = (index * 5 + 1) % _len # search another slot; cpython解决hash冲突的的一种方式。
                continue # while -> next loop
            elif self._table[index].key == key: # find it
                return index
            else:
                index = (index * 5 + 1) % _len
        return None
    
    def _slot_can_insert(self, index):
        return (self._table[index] is HashTable.Unused or self._table[index] is HashTable.Empty) # None or Slot(None, None)
    
    def _find_slot_for_insert(self, key):
        index = self._hash(key)
        _len = len(self._table)
        while not self._slot_can_insert(index): # collision
            index = (index * 5 + 1) % _len
        return index # Dont't worry, read follow -> add and _rehash
    
    def add(self, key, value):
        index = self._find_key(key)
        if index is not None: # this key already exists
            self._table[index].value = value # refresh value of this slot
            return False # not new key
        else:
            index = self._find_slot_for_insert(key)
            self._table[index] = Slot(key, value)
            self.length += 1
            if self._load_factor >= 0.8: # make sure always have space to add
                self._rehash()
            return True # new key-vlue
        
    def _rehash(self):
        old_table = self._table # save old hash table
        newsize = len(self._table) * 2
        self._table = Array(newsize, init=HashTable.Unused) # reinit
        self.length = 0

        for slot in old_table:
            if slot is not HashTable.Unused and slot is not HashTable.Empty: # not None and not Slot(None, None)
                index = self._find_slot_for_insert(slot.key)
                self._table[index] = slot
                self.length += 1

    def get(self, key, default=None):
        index = self._find_key(key)
        if index is None:
            return default # not find return what you want
        else:
            return self._table[index].value # find key's value

    def remove(self, key):
        index = self._find_key(key)
        if index is None:
            raise KeyError() # no this key to remove, so raise error
        value = self._table[index].value # save key's value
        self._table[index] = HashTable.Empty # this slot -> Slot(None, None)
        self.length -= 1
        return value

    def __iter__(self):
        for slot in self._table:
            if slot not in (HashTable.Unused, HashTable.Empty):
                yield slot.key

# 示例演示效果
def test_hash_table():
    h = HashTable()
    h.add('i', 0)
    h.add('miss', 1)
    h.add('u', 2)
    assert len(h) == 3
    assert h.get("i") == 0
    assert h.get("miss") == 1
    assert h.get("him", "No!") == "No!"

    h.remove('i')
    assert h.get('i') is None
    assert len(h) == 2
    assert sorted(h) == ["miss", "u"]

    n = 50
    for i in range(n):
        h.add(i, i)
        
    print(len(h)) # 52
    
    for i in range(n):
        assert h.get(i) == i

if __name__ == '__main__':
    test_hash_table()

标签:index,None,python,self,左神,next,算法,key,._
From: https://www.cnblogs.com/ljdsbfj/p/16600115.html

相关文章

  • python获取对象属性的几种方法
    当我们拿到一个对象的引用时,如何知道这个对象是什么类型、有哪些方法呢?1.使用type()首先,我们来判断对象类型,使用type()函数:基本类型都可以用type()判断:>>>type(123)<......
  • windows下 python virtualenv 虚拟环境安装
    1.  虚拟环境virtualenvironment借助虚拟化技术,把机器中一部分内容独立出来。这部分独立的内容一般被称为“容器”。在这个容器中,我们可以安装需要的依赖包,各个......
  • Python|使用Python实现图像的重采样
    基础知识图像重采样就是从高分辨率遥感影像中提取出低分辨率影像,或者从低分辨率影像中提取高分辨率影像的过程。常用的方法有最邻近内插法、双线性内插法、三次卷积法等。......
  • MySQL多表查询与python操作MySQL
    一、navicateNavicate是一套可创建多个连接的数据库管理工具,用以方便管理 MySQL、Oracle、PostgreSQL、SQLite、SQLServer、MariaDB 和 MongoDB 等不同类型的数据库......
  • python 中实现DNA一致性序列计算
     001、root@PC1:/home/test#lsa.fastatest.pyroot@PC1:/home/test#cata.fasta##测试数据>Rosalind_1ATCCAGCT>Rosalind_2GGGCAACT>Rosalin......
  • Python list methods All In One
    PythonlistmethodsAllInOnePython3#!/usr/bin/envpython3#coding=utf-8__author__='xgqfrms'__editor__='vscode'__version__='1.0.1'__copyrigh......
  • python菜鸟学习: 9. 文件操作
    #-*-coding:utf-8-*-importsys,time#读文件:一次性读取所有内容#r=readf=open("singe.txt",'r',encoding="utf-8").read()print(f)#写文件,覆盖原来的文件#w=wr......
  • 粒子滤波 PF(Particle filter)算法
    原文链接粒子滤波器方法通常用于视觉跟踪。从统计角度来看,它是一种顺序蒙特卡罗重要抽样方法,用于根据观测序列估计动态系统的潜状态变量。粒子滤波步骤:初始状态:用大量......
  • python 读取.pkl.gz文件
    1importpandasaspd2importsix.moves.cPickleascPickle3importgzip45filePath='./a/data.pkl.gz'6f=gzip.open(filePath,'rb')7df=pd.D......
  • 算法提高课 第二章 搜索之DFS
    一、DFS之连通性模型1112.迷宫#include<iostream>#include<cstring>#include<algorithm>usingnamespacestd;constintN=110;intT,n;charg[N][N];in......