【golang 必备算法】哈希表篇

哈希表

242. 有效的字母异位词
func isAnagram(s string, t string) bool {
    var m [26]int
    for _,v:=range s{
        m[v-'a']++
    }

    for _,k:=range t{
        m[k-'a']--
    }

    for _,w:=range m{
        if w!=0{
            return false
        }
    }

return true
}
349. 两个数组的交集
func intersection(nums1 []int, nums2 []int) []int {
    var arr []int
    h:=make(map[int]int,1)
    for _,k:=range nums1{
        h[k]++
    }

    for _,v:=range nums2{
        if h[v]>0{
            arr=append(arr,v)
            h[v]=0
        }
    }

    return arr
}
202. 快乐数

用哈希表来检测循环,出现出过的数就直接返回false

func isHappy(n int) bool {
h:=make(map[int]int,0)

for n!=1{
    if h[n]>0{
        return false
    }
     h[n]++ //要先保存在map中,再更新
n=getsum(n)

}
return true
}

func getsum(n int)int{
    sum:=0

for n>0{
    sum+=(n%10)*(n%10)
    n=n/10
}
    return sum
}
1. 两数之和
func twoSum(nums []int, target int) []int {

    h:=make(map[int]int,len(nums))

    for k,v:=range nums{
       if p,ok:=h[target-v];ok{
            return []int{k,p}
        }
        h[v]=k
    }
    return []int{}
}
454. 四数相加 II
func fourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int) int {
    h:=make(map[int]int)
    var t int
    for _,v1:=range nums1{
        for _,v2:=range nums2{
            h[v1+v2]++
        }
    }

    for _,v3:=range nums3{
        for _,v4:=range nums4{
            t+=h[0-v3-v4]
        }
    }

    return t
}
383. 赎金信
func canConstruct(ransomNote string, magazine string) bool {
    var mag [26]int

    for _,v:=range magazine{
        mag[v-'a']++
    }

    for _,k:=range ransomNote{
        if mag[k-'a']<=0{
            return false
        }else{
            mag[k-'a']--
        }
    }
return true
}
15. 三数之和

两层循环+双指针

func threeSum(nums []int) [][]int {
    var res [][]int

    sort.Ints(nums)
    for i:=0;i<len(nums)-2;i++{
        n1:=nums[i]
        if nums[i]>0{
            break
        }
        if i>0&&nums[i]==nums[i-1]{
            continue
        }

        left:=i+1
        right:=len(nums)-1

        for right>left{
            n2:=nums[left]
            n3:=nums[right]

            if n1+n2+n3==0{
                res=append(res,[]int{n1,n2,n3})
                  for right>left&&nums[left]==n2{
                      left++
                  }
                for right>left&&nums[right]==n3{
                    right--
                }
            }else if n1+n2+n3>0{
                right--
            }else if n1+n2+n3<0{
                left++
            }
        } 
    }
    return res
}
18. 四数之和

每层循环都要去重

func fourSum(nums []int, target int) [][]int {
   res:=[][]int{}
    if len(nums)<4{
        return res
    }
    sort.Ints(nums)
    for i:=0;i<len(nums)-3;i++{
              n1:=nums[i]
            if i>0&& n1 == nums[i-1] {
			    continue
		}
        for j:=i+1;j<len(nums)-2;j++{
                n2:=nums[j]
            if j>i+1&& n2 == nums[j-1] {
			    continue
		}
            l:=j+1
            r:=len(nums)-1
            for l<r{
                n3:=nums[l]
                n4:=nums[r]

                if n1+n2+n3+n4==target{
                    res=append(res,[]int{n1,n2,n3,n4})
                    for l<r&&nums[l+1]==nums[l]{
                        l++
                    }
                    for  l<r&&nums[r-1]==nums[r]{
                        r--
                    }
                         l++
                         r--
                }else if  n1+n2+n3+n4>target{
                    r--
                }else{
                    l++
                }
            }
        }
    }
    return res
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
雪花算法是一种分布式唯一ID生成算法,它可以保证在分布式环境下生成唯一的ID。在Golang中,我们可以使用以下代码实现雪花算法: ```go package main import ( "errors" "fmt" "sync" "time" ) const ( // StartTime 是雪花算法开始时间戳,用于减小生成的ID长度 StartTime = 1577808000000 // 2020-01-01 00:00:00的时间戳,单位毫秒 // MachineIDBits 机器ID的位数 MachineIDBits = 10 // SequenceBits 序列号的位数 SequenceBits = 12 // MachineIDShift 机器ID的移位长度 MachineIDShift = SequenceBits // TimestampShift 时间戳的移位长度 TimestampShift = SequenceBits + MachineIDBits // MaxMachineID 最大机器ID MaxMachineID = -1 ^ (-1 << MachineIDBits) // MaxSequence 最大序列号 MaxSequence = -1 ^ (-1 << SequenceBits) ) // Snowflake 是雪花算法生成的唯一ID结构体 type Snowflake struct { machineID int64 // 机器ID sequence int64 // 序列号 lastStamp int64 // 上次生成ID的时间戳 idLock sync.Mutex } // NewSnowflake 创建一个新的雪花算法实例 func NewSnowflake(machineID int64) (*Snowflake, error) { if machineID < 0 || machineID > MaxMachineID { return nil, errors.New("machine ID out of range") } return &Snowflake{ machineID: machineID, }, nil } // Generate 生成一个新的唯一ID func (s *Snowflake) Generate() int64 { s.idLock.Lock() defer s.idLock.Unlock() // 获取当前时间戳 now := time.Now().UnixNano() / 1e6 // 如果当前时间小于上次生成ID的时间戳,说明系统时间被调整过,此时应该返回错误 if now < s.lastStamp { panic(fmt.Sprintf("time is moving backwards, refusing to generate id for %d milliseconds", s.lastStamp-now)) } // 如果当前时间与上次生成ID的时间戳相同,说明在同一毫秒内生成了多次ID,此时应将序列号+1 if now == s.lastStamp { s.sequence = (s.sequence + 1) & MaxSequence if s.sequence == 0 { // 序列号已经达到最大值,等待下一毫秒 for now <= s.lastStamp { now = time.Now().UnixNano() / 1e6 } } } else { // 当前时间与上次生成ID的时间戳不同,说明已经进入下一毫秒,序列号重置为0 s.sequence = 0 } // 保存当前时间戳,用于下一次生成ID时使用 s.lastStamp = now // 生成ID id := (now-StartTime)<<TimestampShift | (s.machineID << MachineIDShift) | s.sequence return id } func main() { // 创建一个新的雪花算法实例,机器ID为1 sf, err := NewSnowflake(1) if err != nil { panic(err) } // 生成10个唯一ID for i := 0; i < 10; i++ { id := sf.Generate() fmt.Println(id) } } ``` 在上面的代码中,我们首先定义了一些常量,包括开始时间、机器ID的位数、序列号的位数等。然后,我们定义了一个Snowflake结构体,用于保存生成ID时需要用到的一些参数,如机器ID、序列号、上次生成ID的时间戳等。接着,我们定义了NewSnowflake函数,用于创建一个新的雪花算法实例,并检查机器ID是否超出范围。最后,我们定义了Generate函数,用于生成一个新的唯一ID。在Generate函数中,我们首先获取当前时间戳,然后判断当前时间是否小于上次生成ID的时间戳,如果是,则说明系统时间被调整过,此时应该返回错误;如果当前时间与上次生成ID的时间戳相同,则说明在同一毫秒内生成了多次ID,此时应将序列号+1;如果当前时间与上次生成ID的时间戳不同,则说明已经进入下一毫秒,序列号重置为0。最后,我们将当前时间戳、机器ID、序列号组合成一个64位的唯一ID返回。 在main函数中,我们创建了一个新的雪花算法实例,并调用Generate函数生成了10个唯一ID。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值