数组
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 不是if
subLength := j - i + 1 //这是临时窗口长度
if subLength < result {
result = subLength
}
sum -= nums[i]//这两句的意思是,只要sum>target
i++ //左指针就一直往右移动
}
}
if result == l+1 { //这里是如果全部都不符合条件
return 0
} else {
return result
}
}
27. 移除元素
func removeElement(nums []int, val int) int {
res := 0
for _,v :=range nums{
if v != val{
nums[res] = v
res++
}
}
return res
}
977. 有序数组的平方
func sortedSquares(nums []int) []int {
res := make([]int,len(nums))
length := len(nums)-1
l,r := 0,len(nums)-1
for 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-1
left, right := 0, n-1
num := 1
tar := n * n
matrix := 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] = num
num++
}
top++
for i := top; i <= bottom; i++ {
matrix[i][right] = num
num++
}
right--
for i := right; i >= left; i-- {
matrix[bottom][i] = num
num++
}
bottom--
for i := bottom; i >= top; i-- {
matrix[i][left] = num
num++
}
left++
}
return matrix
}
链表
203. 移除链表元素
这里就涉及如下链表操作的两种方式:
- 直接使用原来的链表来进行删除操作。
- 设置一个虚拟头结点在进行删除操作。
移除头结点和移除其他节点的操作是不一样的,因为链表的其他节点都是通过前一个节点来移除当前节点,而头结点没有前一个节点。
所以头结点如何移除呢,其实只要将头结点向后移动一位就可以,这样就从链表中移除了一个头结点。
可以设置一个虚拟头结点,这样原链表的所有节点就都可以按照统一的方式进行移除了。
//前面没想到的地方是设置虚拟节点以后不会怎么设置返回值,如果头节点被删掉,返回谁
func removeElements(head *ListNode, val int) *ListNode {
dummyHead := &ListNode{}//这时候初始化为0,如果是var定义的话就初始化为nil
dummyHead.Next = head
cur := dummyHead
for 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 *ListNode
cur := head
for cur != nil {
next := cur.Next
cur.Next = pre
pre = cur
cur = next
}
return pre
}
//下面这个输出单个元素是错误的,错误的地方是没有提取保存cur的下一个值,就cur.Next = pre
//这样,cur的下一个值就永远找不到了,所以在cur.Next = pre之前要保存一下下一个的节点
func reverseList(head *ListNode) *ListNode {
var pre *ListNode
cur := head
for cur != nil{
cur.Next = pre
head = head.Next
pre = cur
cur = head
}
return pre
}
//下面这个是正确的
func reverseList(head *ListNode) *ListNode {
var pre *ListNode
cur := head
for cur != nil{
head = head.Next
cur.Next = pre
pre = cur
cur = head
}
return pre
}
这里空着设计链表和两两交换链表中的节点
19. 删除链表的倒数第 N 个结点
//这里我错误的地方是没有设置虚拟头节点
func removeNthFromEnd(head *ListNode, n int) *ListNode {
dummyHead := &ListNode{}
dummyHead.Next = head
cur := head
prev := dummyHead
i := 1
for cur != nil {
cur = cur.Next
if i > n {
prev = prev.Next
}
i++
}
prev.Next = prev.Next.Next
return 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, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
if slow == fast {
for slow != head {
slow = slow.Next
head = 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]int
for _, 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 := 0
for 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 := 0
for _, 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)-1
for 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
}