算法与数据结构 大纲

179 阅读2分钟

字符串

  1. 判断是否为回文串

  2. 子串,子数组

    子串子数组都是原字符串原数组的一部分,且必须是连续的

  3. 子序列 vs 子集

    子序列和子数组都是从原先中任意挑出一部分,不要求连续

    子集包含空元素

数组

  1. 如何获取元素的中间索引

    left + ((right -left) >> 1)

  2. 如何构建长度为k的数组,且填充内容为0

    const arr = (new Array(7)).fill(1) // 不可以为一个引用数据类型

  3. 双数组的倒序遍历

    let index1 = arr1.length - 1 let index2 = arr2.index - 1 while(index1>=0 && index2>=0) { if(arr1[index1] >= arr2[index2]) {

    }
    

    } if(index2>=0) {

    }

链表

从i-k有多少个元素?

有k-i+1个元素

从第i移动到第k需要遍历几次

需要k-i次

如何获取到第n个元素

let index = 1
while(index < n) {
  cur = cur.next
}

如何获取倒数第n个元素

倒数第n个,共有n个元素,需要走n-1步到达最后一个

如何获取中间节点

let slow = fast = head

while(fast && fast.next) {
  slow = slow.next
  fast = fast.next.next
}

return slow

如何反转一个链表,最后是停在了那个最后一个元素上嘛?

停留在了最后一个元素的下一个

map && set

如何知道是否有重复元素

map.size < (right-left+1)

如何对map, set类数组进行遍历

for (let item of set) {

}

单调栈

while(stack.length > 0 && cur >= stack[stack.length -1]) {
  stack.pop()
}
if(stack.length>0) {
	res[i].push(stack[stack.length-1])
}else {
	res.push(-1)
}
stack.push(cur)

队列

双端队列

var maxSlidingWindow = function (nums, k) {
  const res = [] , queue = []
  for(let i=0,j= 1-k;i<nums.length;i++,j++) {
      // 位置单调栈
      while(queue.length>0 && nums[i] >= nums[queue[queue.length-1] ]) queue.pop()
       // 删除非法
    	while( queue[0] < j) queue.shift()
    
    	queue.push(i)
      if(j>=0) res.push(nums[queue[0]])
  }
  return res
};

bfs

  1. 把跟节点放入队列中,设置depth = 0
  2. 计算此时队列的length, 设置res[depth] = []
  3. 遍历length,依次取出节点,把节点记录下,然后把左右节点入队
  4. 更新depth++
  5. 当队列不为空时,持续2,3,4步骤

dfs + traveser

function dfs(root) {
  function traveser(root) {
    if(!root) return null
    result.push(root.val)
    traveser(root.left)
    traveser(root.right)
  }
  const result = []
  traveser(root)
  return result
}

dfs + 返回值具有依赖关系

function deepClone(obj={}) {
    if(typeof obj !== 'object' || obj == null) return obj
    const result = obj instanceof Array ? [] : {}
    for(let key in obj) {
        if(obj.hasOwnProperty(key)) {
            result[key] = deepClone(obj[key])
        }
    }
    return result
}

dfs + compare

function dfs(root) {
	function compare(p,q) {
		if(p==null && q==null) return true
		if(p!=null || q!=null) return false
		if(p.val !== q.val) return false
		return compare(p.left,q.left) && compare(p.right, q.right)
	} 

	return compare(root.left,root.right)
}

dfs + backtracking

function dfs(nums) {
	function backtracking(path,startIndex) {
		if(path.length == xx) {
			res.push(path)
		}
		for(let i=startIndex;i<nums.length;i++) {
				backtracking(path.concat(nums[i]),i+1)
		}
	}
}

双指针

单个字符串、数组、链表

  • 针对数组移动,一个记录位置,一个寻找符合要求的值

两个字符串、数组、链表

  • while(l1 ≠ null && l2 ≠ null)
  • while(l1 ≠= null || l2 ≠ null)

二分法

左侧优先二分

右侧优先二分

旋转数组二分

滑动窗口

  1. 设置左右窗口,设置最大,最小值
  2. 设置窗口存储容器
  3. 最短是优中选优,最长是每次比较
  4. 在满足条件时,更新最大最小值