给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
思路
定义变量 last 表示 [0, last) 是满足要求的区间
遍历原始数组,遇到不需要被删除的元素,则扩展满足要求的区间。最后方法返回 last 就是剩下的长度 时间复杂度O(n), 空间复杂度O(1)
实现
1 2 3 4 5 6 7 8 9 10 11 12
funcremoveElement(nums []int, val int)int { // last: 表示 [0, last) 是满足要求的区间 last := 0 for _, v := range nums { if val != v { // 不需要被删除,满足要求区间扩展 nums[last] = v last ++ } } return last }
funcminSubArrayLen(target int, nums []int)int { // 当前窗口为 [left, right) left, right := 0, 0 curSum := 0 result := math.MaxInt for right < len(nums) { // 将 right 放入窗口 curSum += nums[right] right ++ // 进行判断是否满足要求 for curSum >= target { // 满足要求,尝试更新结果 if right - left < result { result = right - left } // 尝试减少左侧的数据 curSum -= nums[left] left ++ } } if result == math.MaxInt { return0 } return result }
// 1. 找到长短链表 len1, len2 := 0, 0 for tmpA != nil { len1 ++ tmpA = tmpA.Next } for tmpB != nil { len2 ++ tmpB = tmpB.Next } var long, short *ListNode var distance int if len1 > len2 { long = headA short = headB distance = len1 - len2 } else { long = headB short = headA distance = len2 - len1 }
// 2. 长的先走 n 步, 然后同时走 for i := 0; i < distance; i++ { long = long.Next } for long != nil && short != nil { if long == short { return long } long = long.Next short = short.Next } returnnil }
fast 每次走两步, slow 每次走一步, 当 fast 为 nil 的时候,说明链表没有环,直接返回 nil
当 fast 和 slow 相遇的时候,说明出现了环,此时将 fast 返回到 head 的位置
接着 fast 和 slow 同时走,当 fast == slow 的时候,就找到了入环第一个节点
实现
实现1
1 2 3 4 5 6 7 8 9 10 11
funcdetectCycle(head *ListNode) *ListNode { m := map[*ListNode]struct{}{} for head != nil { if _, ok := m[head]; ok { return head } m[head] = struct{}{} head = head.Next } returnnil }
实现2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
funcdetectCycle(head *ListNode) *ListNode { fast, slow := head, head for fast != nil && fast.Next != nil { fast = fast.Next.Next slow = slow.Next
if fast == slow { // 追到的话,肯定有环 fast = head for fast != slow { fast = fast.Next slow = slow.Next } return fast } } returnnil }
funcisAnagram(s string, t string)bool { m := map[rune]int{} // 记录 s 出现的次数
for _, ch := range s { m[ch] ++ } for _, ch := range t { m[ch]-- if m[ch] < 0 { returnfalse } } for _, v := range m { if v != 0 { returnfalse } } returntrue }
funcintersection(nums1 []int, nums2 []int) []int { result := make([]int, 0) resultSet := make(map[int]struct{}) m := make(map[int]struct{})
for _, n := range nums1 { m[n] = struct{}{} } for _, n := range nums2 { if v, ok := m[n]; ok { resultSet[n] = v } } for k, _ := range resultSet { result = append(result, k) } return result }
维护字典 m, 每次遍历将遍历到的 value 作为 key, index 作为 value 放入字典中
每次遍历的时候,判断 target - value 是否存在于字典中,如果存在,说明找到了,返回即可
实现
1 2 3 4 5 6 7 8 9 10 11
functwoSum(nums []int, target int) []int { m := make(map[int]int) // value -> index for i, v := range nums { aim := target - v if index, ok := m[aim]; ok { return []int{i, index} } m[v] = i } returnnil }
/** * Definition for a binary tree node. * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */
funcpreorderTraversal(root *TreeNode) []int { var result = make([]int, 0) var t func(*TreeNode) t = func(root *TreeNode) { if root == nil { return } result = append(result, root.Val) t(root.Left) t(root.Right) } t(root) return result }