0
点赞
收藏
分享

微信扫一扫

LeetCode刷题(剑指offer)

女侠展昭 2022-03-11 阅读 56
leetcode

offer_1

前言:

因为实在是太菜了,所以先刷剑指offer,然后暴力永远的神

1.二维数组中的查找

题目描述

题目分析:
这个题目应该有多种思路来解决,
其中最容易想到的是暴力.直接遍历整个数组,然后寻找相似项.如果存在相似项则返回true,不存在相似项返回false.

但是如果这样写的话,就没有利用题目的条件,面试也可能到此为止了.
可以利用题目条件,使用线性查找的方法.
方法一:暴力

func findNumberIn2DArray(matrix [][]int, target int) bool {
	num:=make(map[int]bool)	
	for i:=0;i<len(matrix);i++{
		for j:=0;j<len(matrix[0]);j++ {
			num[matrix[i][j]] = true
		}
	}
	_,ok := num[target]
	return ok
}

因为这两天补习了一下map的相关知识,所以下意识就使用了map的特性进行解题.
思路很简单:将所有的数据存储到map中,然后判断map中是否存在指定数.

一般来说,如果使用暴力法,应该直接遍历,使用map的话比较占用内存.
这种方法执行用时比较长(又不是不能用)

方法二线性查找:
这是比较推荐的一种方法,充分利用了题目的条件.

先分析思路:
根据官方题解:

利用这个二维数组的特性,在每次查找的时候都可以把一部分的元素排除.
从右上角出发,依次遍历,每次都可以排除元素

func findNumberIn2DArray(matrix [][]int, target int) bool {
    if len(matrix) == 0 {
        return false
    }
    i, j := 0, len(matrix[0]) - 1
    for i < len(matrix) && j >= 0 {
        if matrix[i][j] == target {
            return true
        } else if matrix[i][j] < target {
            i++
        } else {
            j--
        }
    }
    return false
}

2. 0~n-1中缺失的数字

题目描述:

思路分析
因为这个是一个递增的排序数组,那首先就应该想到使用二分法进行解题.

根据题意,数组可以按照以下规则划分为两部分。

分析题目可以发现:缺失的数字等于右子数组的首位元素对应的索引,因此考虑使用二分法查找右子数组的首位元素.

解法一:暴力
虽然很low,但是暴力也是一种解法,通过遍历可以直接找到右子树的下标

func missingNumber(nums []int) int {
    size := len(nums)

    for i:=0; i<size; i++ {
        if nums[i] != i {
            return i
        }
    }

    return size
}

在这道题中,暴力解法效果还行

解法二:二分查找

func missingNumber(nums []int) int {
    left,right := 0, len(nums)-1
    for left <= right {
        mid := left + (right-left)/2
        if nums[mid] == mid {
            left = mid + 1
        }else{
            right = mid - 1 
        }
    }
    return left
}

速度和暴力差不多
解法三:按位异或

func missingNumber(nums []int) int {
    n := len(nums)
    for k:= range nums{
            n ^= k ^ nums[k]
    }
    return n
}

看了"sakura-151"的题解,我发现这个解法,非常的巧妙,解释如下:

3. 在排序数组中查找数字

题目描述:

方法一:暴力
暴力或许会迟到,但永远不会缺席.对于我这样的小白来说,暴力是最容易想到的.虽然不应该经常暴力法,但是在学的过程中,应该尽可能地把想法全部实现.

func search(nums []int, target int) int {
	sum:=0
	for _,i :=range nums{
		if i == target{
			sum++
		}
	}
	
	return sum
}

效果还行
方法二:二分查找
因为这个是一个排序数组,所以另一个可以快速想到的方法就是二分查找.
考虑到会有多个数与target相同,先使用二分查找寻找最左边的与target数值相等的数,然后再使用二分查找寻找到最右边与target相等的数,left-right就是结果

func search(nums []int, target int) int {
    left := sort.SearchInts(nums, target)
    if left == len(nums) || nums[left] != target {
        return 0
    }
    right := sort.SearchInts(nums, target + 1)
    return right - left
}

这一次,暴力法全胜.

4.左旋转字符串

题目描述


题目分析
这题非常简单,没啥好讲的,就是吧指定的字符放到字符串的前端就好.

使用go的话,一行就可以得出结果:

func reverseLeftWords(s string, n int) string {
	return s[n:]+s[:n]
}

5.复杂链表的复制

题目描述

题目分析
看到这个题目我最先想到的是一种偷懒的方法:

func copyRandomList(head *Node) *Node {
  return head  
}

但是结果却是:

看来我被官方拿捏的死死的.
既然不能偷懒,那就好好分析:
这个题目的意思还是有点难理解的.
官方题解的介绍如下:

func deepCopy(node *Node) *Node {
    if node == nil {
        return nil
    }
    if n, has := cachedNode[node]; has {
        return n
    }
    newNode := &Node{Val: node.Val}
    cachedNode[node] = newNode
    newNode.Next = deepCopy(node.Next)
    newNode.Random = deepCopy(node.Random)
    return newNode
}

func copyRandomList(head *Node) *Node {
    cachedNode = map[*Node]*Node{}
    return deepCopy(head)
}

ERROR: Repository not found.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
FATAL {
err: Error: Spawn failed
at ChildProcess. (D:\CodeLife\root\blog\node_modules\hexo-util\lib\spawn.js:51:21)
at ChildProcess.emit (node:events:390:28)
at ChildProcess.cp.emit (D:\CodeLife\root\blog\node_modules\cross-spawn\lib\enoent.js:34:29)
at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12) {
code: 128
}
} Something’s wrong. Maybe you can find the solution here: %s https://hexo.io/docs/troubleshooting.html

举报

相关推荐

0 条评论