数组
209. 长度最小的子数组
题目
思路
双指针,一开始都指向下标为0,开始移动右指针,移动的过程中计算求和,当求和大于target的时候就左指针右移一位。求和减去左指针的值。当右指针遍历完一遍,具体看下面代码
代码
func minSubArrayLen(target int, nums []int) int {i := 0 //左指针,j为右指针l := len(nums) // 数组长度sum := 0 // 子数组之和result := l + 1 // 初始化返回长度为l+1,目的是为了判断“不存在符合条件的子数组,返回0”的情况for j := 0; j < l; j++ {sum += nums[j]for sum >= target { //这里注意是for 不是ifsubLength := j - i + 1 //这是临时窗口长度if subLength < result {result = subLength}sum -= nums[i]//这两句的意思是,只要sum>targeti++ //左指针就一直往右移动}}if result == l+1 { //这里是如果全部都不符合条件return 0} else {return result}}
27. 移除元素
func removeElement(nums []int, val int) int {res := 0for _,v :=range nums{if v != val{nums[res] = vres++}}return res}
977. 有序数组的平方
func sortedSquares(nums []int) []int {res := make([]int,len(nums))length := len(nums)-1l,r := 0,len(nums)-1for l <= r{if nums[l]*nums[l] <= nums[r]*nums[r]{res[length] = nums[r]*nums[r]r--length--}else{res[length] = nums[l]*nums[l]l++length--}}return res}
59. 螺旋矩阵 II

func generateMatrix(n int) [][]int {top, bottom := 0, n-1left, right := 0, n-1num := 1tar := n * nmatrix := make([][]int, n)for i := 0; i < n; i++ {matrix[i] = make([]int, n)}for num <= tar {for i := left; i <= right; i++ {matrix[top][i] = numnum++}top++for i := top; i <= bottom; i++ {matrix[i][right] = numnum++}right--for i := right; i >= left; i-- {matrix[bottom][i] = numnum++}bottom--for i := bottom; i >= top; i-- {matrix[i][left] = numnum++}left++}return matrix}
链表
203. 移除链表元素

这里就涉及如下链表操作的两种方式:
- 直接使用原来的链表来进行删除操作。
- 设置一个虚拟头结点在进行删除操作。
移除头结点和移除其他节点的操作是不一样的,因为链表的其他节点都是通过前一个节点来移除当前节点,而头结点没有前一个节点。
所以头结点如何移除呢,其实只要将头结点向后移动一位就可以,这样就从链表中移除了一个头结点。
可以设置一个虚拟头结点,这样原链表的所有节点就都可以按照统一的方式进行移除了。
//前面没想到的地方是设置虚拟节点以后不会怎么设置返回值,如果头节点被删掉,返回谁func removeElements(head *ListNode, val int) *ListNode {dummyHead := &ListNode{}//这时候初始化为0,如果是var定义的话就初始化为nildummyHead.Next = headcur := dummyHeadfor cur != nil && cur.Next != nil {if cur.Next.Val == val {cur.Next = cur.Next.Next} else {cur = cur.Next}}return dummyHead.Next}
206. 反转链表

首先定义一个cur指针,指向头结点,再定义一个pre指针,初始化为null。
然后就要开始反转了,首先要把 cur->next 节点用tmp指针保存一下,也就是保存一下这个节点。
为什么要保存一下这个节点呢,因为接下来要改变 cur->next 的指向了,将cur->next 指向pre ,此时已经反转了第一个节点了。
接下来,就是循环走如下代码逻辑了,继续移动pre和cur指针。
最后,cur 指针已经指向了null,循环结束,链表也反转完毕了。 此时我们return pre指针就可以了,pre指针就指向了新的头结点
//这个是正确的,建议用这个func reverseList(head *ListNode) *ListNode {var pre *ListNodecur := headfor cur != nil {next := cur.Nextcur.Next = prepre = curcur = next}return pre}//下面这个输出单个元素是错误的,错误的地方是没有提取保存cur的下一个值,就cur.Next = pre//这样,cur的下一个值就永远找不到了,所以在cur.Next = pre之前要保存一下下一个的节点func reverseList(head *ListNode) *ListNode {var pre *ListNodecur := headfor cur != nil{cur.Next = prehead = head.Nextpre = curcur = head}return pre}//下面这个是正确的func reverseList(head *ListNode) *ListNode {var pre *ListNodecur := headfor cur != nil{head = head.Nextcur.Next = prepre = curcur = head}return pre}
这里空着设计链表和两两交换链表中的节点
19. 删除链表的倒数第 N 个结点

//这里我错误的地方是没有设置虚拟头节点func removeNthFromEnd(head *ListNode, n int) *ListNode {dummyHead := &ListNode{}dummyHead.Next = headcur := headprev := dummyHeadi := 1for cur != nil {cur = cur.Nextif i > n {prev = prev.Next}i++}prev.Next = prev.Next.Nextreturn dummyHead.Next}
面试题 02.07. 链表相交

使用哈希表
func getIntersectionNode(headA, headB *ListNode) *ListNode {m := make(map[*ListNode]int)for headA != nil{m[headA]++headA = headA.Next}for headB != nil{_,ok := m[headB]if ok{return headB}headB = headB.Next}return nil}
142. 环形链表 II

func detectCycle(head *ListNode) *ListNode {slow, fast := head, headfor fast != nil && fast.Next != nil {slow = slow.Nextfast = fast.Next.Nextif slow == fast {for slow != head {slow = slow.Nexthead = head.Next}return head}}return nil}
哈希表
349. 两个数组的交集

//我的写法func isAnagram(s string, t string) bool {if len(s)!=len(t){return false}m := make(map[byte]int)for _,v := range s{m[byte(v)]++}for _,k := range t{_,ok := m[byte(k)]if ok {if m[byte(k)] == 0{return false}else{m[byte(k)]--}}else{return false}}return true}//比较好的答案func isAnagram(s, t string) bool {var c1, c2 [26]intfor _, ch := range s {c1[ch-'a']++}for _, ch := range t {c2[ch-'a']++}return c1 == c2}
349. 两个数组的交集

//我的做法func intersection(nums1 []int, nums2 []int) []int {m := make(map[int]int)res := []int{}for _,v := range nums1{m[v]++}for _,k := range nums2{_,ok := m[k]if ok && m[k] != 0{res = append(res,k)m[k] = 0//这一步的意思就是,我往res中以及添加了k元素,后面再遇到就不再添加了}}return res}//答案func intersection(nums1 []int, nums2 []int) []int {res := []int{}m := map[int]int{}for _,v := range nums1{m[v]++}for _,k := range nums2{_,ok := m[k]if ok != false{res = append(res,k)delete(m,k)}}return res}
202. 快乐数

这道题目使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。判断sum是否重复出现就可以使用哈希表。
func isHappy(n int) bool {m := make(map[int]bool)for n != 1 && !m[n] {n, m[n] = getSum(n), true}return n == 1}func getSum(n int) int {sum := 0for n > 0 {sum += (n % 10) * (n % 10)n = n / 10}return sum}
454. 四数相加 II

func fourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int) int {m := make(map[int]int)count := 0for _, v1 := range nums1 {for _, v2 := range nums2 {m[v1+v2]++}}for _, v3 := range nums3 {for _, v4 := range nums4 {count += m[-v3-v4]}}return count}
383. 赎金信

//我的代码,没有标准答案好func canConstruct(ransomNote string, magazine string) bool {m := make(map[byte]int)for i,_ := range magazine{m[magazine[i]]++}for i,_ := range ransomNote{_,ok := m[ransomNote[i]]if ok{m[ransomNote[i]]--if m[ransomNote[i]] == 0{delete(m,ransomNote[i])}}else{return false}}return true}//答案func canConstruct(ransomNote string, magazine string) bool {record := make([]int, 26)for _, v := range magazine {record[v-'a']++}for _, v := range ransomNote {record[v-'a']--if record[v-'a'] < 0 {return false}}return true}
15. 三数之和

func threeSum(nums []int)[][]int{sort.Ints(nums)res:=[][]int{}for i:=0;i<len(nums)-2;i++{n1:=nums[i]if n1>0{break}if i>0&&n1==nums[i-1]{continue}l,r:=i+1,len(nums)-1for l<r{n2,n3:=nums[l],nums[r]if n1+n2+n3==0{res=append(res,[]int{n1,n2,n3})for l<r&&nums[l]==n2{l++}for l<r&&nums[r]==n3{r--}}else if n1+n2+n3<0{l++}else {r--}}}return res}
