视频笔记

(1)算法与数据结构:
任务的安排,不要先入先出。采用优先队列
加密货币,区块链。
必要条: 算法与数据及结构。
算法和数据结构是有用和有趣的。
Binary Tree 链表和数结合区块链。
(2)如何事半功倍的学习算法
《outliers》
chunk it up  切碎成知识点
Deliberate practicing  刻意练习
Feedback   反馈
星际争霸: 控兵  运营
Sorting  Link_list list spanning tree
Tree_Graph  Stack  Hashing
 
 Abstrack_data_type{
   stack{Vector};
   Queue{Linked List,
     Priority Queue{
      Heap
       }
     };
   SetP{Hash Set,
    Tree Set
    }
   Map{
    Hash Map,
    Tree Map
   }
 }

Data struct  Aglum
刻意练习:
Feedback 反馈:
主动反馈,
被动反馈。算法和面试题。
(03)如何计算算法的复杂度
Algorithm
时间复杂度,空间复杂度。
Big O notation
O(1): 常数级
O(N): for循环
O(N^2):for嵌套
O(log(n)): for(int i=0;i<n;i = i*2)
O(k^N): for(int i=0; i<math.pow(2,n);i++)
O(n!):for(int i=0; i<=factorial(n);i++)
累加: 从O(n)---->O(1);
def fib(n):
 if n==0 or n==1:
  return n
 return fib(n-1)+fib(n-2)
常见的算法:
(4):通过leetCode来进行算法题目练习
坚持,刻意练习
https://leetcode.com/problemset/all/
array[2,7,11,15]  target = 9
return index
/*
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
return 一个对象
*/
class Solution:
 def twoSum(self,nums,target): #nums is array
  hash_map = dict()  #定义一个map
  for i, x  in enumerate(nums):  #枚举
   if target - x in hash_map:  #查找是否存在
    return [i,hash_map[tatget-x]] #如果存在则把两个都返回
   hash_map[x]=i #不存在则放入map

(5)理论讲解
数组插入:时间复杂度O(N)
链表:插入删除O(1)  查找O(N)
[head]  [data,next] [data,next]
 反转链表:
 def reverseList(self,head):
  cur,prev = head, None
  while cur:
   cur.next,prev,cur = prev,cur,cur.next
  return prev
 节点反转:
 def swapPairs(self,head):
  pre, pre.next = self,head
  while pre.next and pre.next.next:
   a = pre.next
   b = a.next
   prev.next, b.next, a.next = b,a,b.next
   pre = a
  return self.next
 判断是否有环:
def hanCycle(self,head):
 fast = slow = head
 while slow and fast and fast.next:
  slow = slow.next
  fast = fast.next.next
  if slow is fast:
   return True
 return False
07 堆栈和队列
消息队列的
www.bigocheatsheet.com
08 判断括号是否有效:
string 大众小括号是否匹配
def isValid(self,s):
 stack = []
 paren_map = {')':'(',']':'[','}':'{'}
 for c in s:
  if c not in  paren_map:   # 返回的是key 是左括号入栈
   stact.append(c)
  elif not stack of paren_map[c] !=stack.pop():
   return False
 return not stack  #如果不为空
 public boolean isValid(String s)
 {
   int lenght;
   do{
    lenght = s.length();
    s = s.replace("()","").replace("{}","").replace("[]","");

   }while(lenght != s.length())
   return s.lenght() == 0
 }
10 优先队列
用堆实现,二叉搜索树 Mini Heap
11 返回数据流中的第k大的元素
12 返回滑动窗口中最大的值
13 映射和集合
HashMap  HashSet  TreeMap  TreeSet
Hash  Function
108+105+101+115  = 429  429%30 = 9 
Hash 碰撞:  拉链法
list_x = [1,2,3,4]
map_x = {
 
 'jack': 100,
 '张三':80,
 'selina':90
}
set_x = {}O(1)的时间复杂度
Hash  的时间复杂度 O(1)
python: 
dict   hashMap
std::unorderedmap
std::map 
14:有效的字母异位
 1 排序  --》对比  时间复杂度: log(n)
 2 使用map 字母计数    时间复杂度: O(N)
Valid Anagram
def isAnagram3(self,s,t):
 return sorted(s) == sorted(t)
def isAnagram1(self,s,t):
 dict1, dict2 = {},{}
 for item in s:
  dict[item] = dict.get(item,0)+1
 for item in t:
 #default -- 如果指定键的值不存在时,返回该默认值值。
  dict[item] = dict.get(item,0)+1
 return dict == dict

def isAnagram2(self,s,t):
 dict1 , dict2 = [0]*26, [0]*26 #创建一个数组
 for item in s:
  dict[ord(item)-ord('a')] +=1
 for item in t:
  dict[ord(item)-ord('a')] +=1
 return dict1 == dict2
16  查找数组中三个数的求和为一个定值
 1 暴力: a,b,c,-->3*Loop
 2 map set 
 3 !Loop sorted find
def threeSum(self,nums):
 if len(nums) < 3:   #数组长度
  return []
 nums.sort()  #排序
 res = set()  #集合
 for i,v in enumerate(nums[:-2]):
  if i >= 1 and v == nums[i-1]:  去重
   continue
  d  = {} 空的字典
  for x in nums[i+1:]:
   if x not in d:
    d[-v-x] = 1
   else:
    res.add((v,-v-x,x))
 return map(list,res)

def threeSum(self,nums):
 res = []
 nums.sort()
 for i in xrange(len(nums)-2):
  if i> 0 and num[i] == nums[i-1]
   continue
  l,r = i+1,len(nums)-1
  while l<r:
   s = nums[i]+ nums[l]+ nums[r]
   if s < 0:  l += 1
   else s > 0: r -=1
   else:
    res.appendd((nums[i],nums[l],nums[r]))
   while l < r and nums[l] == nums[l+1]:  去重处理
    l+=1
   while l < r and nums[r] == nums[r-1]:
    r -= 1
   l +=1 ;r -=1
 return res
Binary Tree
root   sub-tree  left-tree  
分层打印二叉树
Graph:
binary search Tree
18 判断是否是二叉排序树:  时间复杂度
   1中序遍历 后 升序  左 根 右
   2 recursion: validate 
中序变量  左根右
def isValidBST(self,root):  判断是否是二叉树
 inorder = self.inorder(root)
 return inorder = list(sorted(set(inorder)))
def inorder(self,root):
 if root is None:
  return
 return self.inorder(root.letf) + [root.val] + self.inorder(root.right)  返回的序列    低效

中序遍历:  不需要全部罗列,只需要保存当前节点
def isValidBST(self, root):
 self.prev = None;
 return self.helper(root)
def helper(self, root):
 if root is None:
  return True
 if not self.helper(root.left):
  return False
 if self.prev and self.prev.val >= root.val:
  return False
 self.prev = root
 return self.helper(root.right)
 
public boolean isValid(TreeNode root,integer min,Integer max)
{
 if (root == null) return true;
 if (min !=null && root.val <= min) return false;
 if (max != null && root.val >= max) return false;
 return isValid(root.left,mix,root.val)&&
     isValid(root.right,root.val,max);
 
}
19 二叉树二叉树搜索
 1 查找公共祖先: 寻找路径path封装两个节点
找到q记下路径  找到p记下了路径  找到公共系节点
 2 Recursion _findPorq(root,p,q)  时间复杂度 O(N)
  if root == q or root ==p
  findPorq(root.left,p,q)
  findPorq(root.right,p,q)

TreeNode lowestCommonAncestor(TreeNode root, TreeNode p,TreeNode q)

 if (root == null || root == p || root == q) return root;
 TreeNode left = lowestCommonAncestor(root.left, p,q);
 TreeNode right = lowestCommonAncestor(root.right,p,q);
 如果左边也包含 右边也包含  当前节点就是公共节点
 return left == null ? right : right == null ? left : root;
}
二叉搜索树 左边的小于 root 右边的大于root
def lowestCommonAncestor(self, root, p,q):
 if p.val < root.val > q.val:
  return self.lowestCommonAncestor(root.left,p,q)
 if p.val > root.val < q.val:
  return self.lowestCommonAnccestor(root.right,p,q)
 return root
循环方法
def lowestCommonAncestor(self,root,p,q):
 while root:
  if p.val < root.val > q.val:
   root = root.left
  elif p.val > root.val < q.val:
   root = root.right
  else:
   return root
20 二叉树的遍历:
Pre_order  根左右
def preorder(self,root):
 if root:
  self.traverse_path.append(root.val)
  self.preorder(root.left)
  self.preorder(root.right)
In_order   左根右
def inorder(self,root):
 if root:
  self.inorder(root.left)
  self.traverse_path.append(root.val)
  self.inorder(root.right)
Post_order 左右根
def postorder(self,root):
 if root:
  self.postorder(root.left)
  self.postorder(root.right)
  self.traverse_path.append(root.val)
实用度小
实用度高的广度和深度
21 递归&分治
是一种循环。自己调用自己。死循环,死递归
盗梦空间
一层--》二层--三层--四层(中止)--三层--二层--一层
n!
def Factorial(n):
 if n<=1:   终止条件
  return 1
 return n*Factorial(n-1)
开始判断层级,
def recursion(level,param1,param2,...):
 终止条件
 if level > MAX_LEVEL:  到达层次限制 返回
  print_result
  return
  业务逻辑
 process_data(level,data...) 做自己要做的事
 调用下一层
 self.recursion(level+1,p1,..)
 收尾工作
 reverse_state(level)
fib
def fib(n):
 if n==0 or n==1:
  return n
 return fib(n-1)+f(n-2)
分治: Divde& Conquer
动态规划,子问题记忆

def divide_conquer(problem,param1,param2,..)
 if problem is None:
  print_result
  reutrn
 data = prepare_data(problem)
 subproblems = split_problem(problem,data)
 subresult1 = self.divide_conquer(subproblems[0],p1,...)
 subresult1 = self.divide_conquer(subproblems[0],p1,...)
 subresult1 = self.divide_conquer(subproblems[0],p1,...)
 ...
 result = process_result(subresult1,subresult1,subresult1)
Pow(x,n)
    1调用库函数 0(1)
    2暴力;O(N)
    3分治 O(log(n))
def myPow(self,x,n):
 if not m:
  return 1
 if n<0:
  return 1/self.myPow(x,-n)
 if n%2:
  reutrn x*self.myPow(x,n-1)
 return self.myPow(x*x,n/2)
非递归
def myPow(self,x,n):
 if n<0:
  x = 1/x
  n = -n
 pow = 1  用于结果返回
 while n:
  if n&1:
   pow * = x
  x *= x
  n >>=1  等于n除以2
 return pow
23找出的数组的元素的出现的次数大于 2分之长度的element
 1 暴力循环:两层循环 count(x) 复杂度O(N平方)
 2Map {x(key):count(值)} 时间复杂度O(N)
 空间O(N)
 3sort 时间复杂度O(NlogN)
 4分治 数组一分为二,左边寻找 右边查找
 return count(left) > count(right) ? left : right
 时间复杂度O(NlogN)
24贪心算法
在当前看来最好选择
算价值36的面额的纸币
问题能过分成子问题来解决。最优子结构。
贪心算法,对每个子问题的解决方案都做出选择,不能回退。 动态规划则会保存以前的运算结果。并根据以前的结果对当前进行选择。有回退功能。
25买卖股票问题
 搜索贪心算法
 最多持有1股  买卖无数次
 1 搜索DFS 时间复杂度O(N)
 2 贪心法每日买卖O(n)
 3 DP时间复杂度O(n)
26 广度优先搜索
 寻找特定的节点。在二叉树中怎么查找value == 100
 计算机查找: 内存扫荡,整个数据的扫荡
 一层一层访问。地毯式搜索。将一层一层的加入队列。
def BFS(graph,start,end):
 queue = []  数组
 queue.append([start])
 visited.add(start)  任何被访问的加入集合
 while queue:
  node = queue.pop()
  visited.add(node)  标记已经被访问过
  process(node)
  找后继节点,没有没有被问过 访问
  nodes = generate_related_nodes(node)
  queue.push(nodes)
27 深度优先搜索
 为什么要深度搜索?计算机一根经一查到底。
visited = set()  保存访问过的节点
def dfs(node,visited):
 visited.add(node)
 ...
 for next_node in node.children:
  if not next_node in visited:
   dfs(next_node,visited)
def DFS(self,tree):
 if tree.root is Node:
  return []
 visited,stackt = [],[tree.root]
 while stack:
  #访问节点
  node = stack.pop()
  添加到访问集
  visited.add(node)
  process(node)
  nodes = generate_related_nodes(node)
  stack.push(nodes)
28 对二叉树按层输出节点:
 1 BFS  广度优先 判断属于那一层
   循环  时间复杂度O(N)
 2 DFS  数组,记住深度。
class Solution(object):
 def levelOrder(self,root):
  if not root: return []
  result = []
  queue = collections.deque() 双端队列
  把根节点加入
  queue.append(root)
  #visited = set(root)
  while queue:
   取出层的长度
   level_size = len(queue)
   current_level = []
   for _ in rang(level_size):
    #取出当前层中队列中的节点
    node = queue.popleft()
    取出当前层中节点的值
    current_level.append(node.val)
    把节点的下一层放入队列
    if node.left: queue.append(node.left)
    if node.right: queue.append(node.right)
   result.append(current_level)
  return result
深度优先
class Solution(object):
 def levelOrder(self,root): 获得根节点
  if not root: return []
  self.result = []  返回集
  self._dfs(root,0) 调用函数
  return self.result
  参数: 节点 深度
  私有函数
 def _dfs(self,node,level):
  if not node: return 
  结果比当前行还要小
  if len(self.result) < level+1:
   self.result.append([])
   一维为层  二维为值
  self.result[level].append(node.val)
  self._dfs(node.left,level+1)
  self._dfs(node.right,level=1)

29 二叉树最大最小的深度:
 2 BFS 按层扫荡 判断是否是叶子接待你
 3 退进,记住max ,min 时间复杂度o(n)
找最大深度;
class Solution:
 def maxDepth(self,root):
  if not root: return 0
  1 自己本身深度的一层
  return 1+max(self.maxDepth(root.left),self.maxDepth(root.right))
class Solution{
 public:
  int minDepth(TreeNode* root)
  {
   if(!root) return 0;
   if(!root->left) return 1+minDepth(root->left);
   if(!root-right) return 1+minDepth(root->right)
   分治
   int leftMinDepth = minDepth(root->left);
   int rightMinDepth = minDepth(root->right);
   返回当前层的最小深度
   int result = 1 + min(leftMinDepth,rightMinDepth);
   return result; 
  }

}
java
public class Solution{
 public int minDepth(TreeNode root){
 if (root == NULL) return 0;
 int left = minDepth(root.left);
 int right = minDepth(root.right);
  左右的较小者加1
 return (left ==0 || right ==0) ? left + right +1 : Math.min(left,right)+1;
 }
}

30 生成括号:
 给定一个n , 输出所有匹配的括号
 1 数学归纳法
 2 递归搜索,字符串的长度为2 * n
 把所有的可能配皮全部罗列出来,去除不合法的
 3 1 局部不合法减枝,不再递归
   2 leftused, rightused O(2的n次方)
class Solution(object);
 def generationParenthesis(self,n):
  self.list = []
  self._gen(0,0,n," ")
  return self.list
  左边的括号已经用了多少个
 def _gen(self,left,right,n,reslet):
 终止条件 括号的数量是否已经用完了
  if left == n and right ==n:
   self.list.append(result)
   return
  if left < n:
   self._gen(left + 1,right, n,result+"(")
  if left > right and right < n:
   self._gen(left,right+1,n,result +")")
31 剪枝
32 N-queues
    DFS 搜索
    枚举列,第一层放置位置,判断能不能方
    1 暴力
    2 剪枝 数组row[i],col[j] 把行和列标志为1
    pie[i+j] = 1
    na[i-j] = 1
    遍历level 判断当前层是否有i,j是否满足
    遍历下一层
def solveNQueue(self,n):
f
 if n<1 return []
 结果集
 self.result = []
 self.cols = set();self.pie = set();self.na = set()
 self.DFS(n,0,[])
 return self.result
def DFS(self,n,row,cur_state):
 终止条件
 if row >=n:
  把结果放入结果集
  self.result.append(cur_state)
  return
 for col in rang(n):
  列被之前占用
  if col in self.cols or row + col in self.pie or row -col in self.na:
   continue
   把皇后放入这个位置
  没有占用把这一行放入结果集 
  self.cols.add(col)
  self.pie.add(row+col)
  self.na.add(row-col)
  self.DFS(n,row+1,cur_state+[col])
  清空现场
  self.cols.remove(col)
  self.pie.remove(row+col)
  self.na.remove(row-col)
def _geerate_result(self,n):
 board = []
 for res in self.result:
  for i in res:
   board.append(.*i+'Q'+'.'*(n-i))
 return [board[i: i+n] for i in range(0,len(board),n)]
 range(start, stop[, step])
参数说明:
start: 计数从 start 开始。默认是从 0 开始。例如range(5)等价于range(0, 5);
stop: 计数到 stop 结束,但不包括 stop。例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5
step:步长,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1)
def so(self,n):
     def df(queue,xy_dif,xy_sum):
             p = len(queue)
             if p == n:
                     result.append(queue)
                     return None
             for q in range(n):
                     if q not in queue and p-q not in xy_dif and p+q not in xy_sum:
                             df(queue+[q],xy_dif+[p-q],xy_sum+[p+q])
     result = []
     df([],[],[])
     生成二维数组
     print ([["."*i+"Q"+"."*(n-i-1) for i in sol] for sol in result])
public void solveSudoku(char[][] board)
{
 if (board == null || board.lenght ==0) return ;
 solve(board);
}
public blooean solve(char [][] board)
{
 for (int i = 0; i < board.length;i++) for (int j < board[0].length; j++){
   if (board[i][j] == "."){
        for (char c = '1'; c <= '9'; c++){
          if (isvalid(board,i,j,c)){
      board[i][j] = c;
       递归调用
       if (solve(board))
      return true
       else
        不然 还原
      board[i][j] = '.';
     }end 判断合法
       }end 枚举可以放入的字符
       1-9 都不能放入 返回
       return  false;
     } end 判断是否为空格
    }
 return true
}
// 判断是否有重复的
private boolean isValid(char[][] board, int row, int col, char c){
 // 9*9的方格
 for(int i = 0;i < 9; i++)
 {
   if(board[i][col] != '.' && board[i][col] ==c) return false;  // check row
   if(board[row][i]!= '.' && board[row][i]== c) return false; check column
   if(board[3*(row/3) + i /3][3* (col/3)+i%3] !='.' && board[3*(row/3) + i /3][3* (col/3)+i%3]  == c) return false; //check 3*3
 }
return true;
}

34 二分查找  时间复杂度log(n)
left, right = 0,len(array)-1
while left <= right:
 mid = (left + right)/2
 if array[mid] == target:
   brear or return result
 elif array[mid] < target :
   left = mid + 1
 else :
  right = mid -1

35  开平方
 target = 5
 1 二分法查找
 2 牛顿迭代法
double squrt(int x, double flag){
 if(x == 0||x == 1) return x;
 int l = 1, r = x, res;
 while (l <=r){
   int m = (l+r)/2
   if (m == x/m){
   return m;
   }else if (m > x /m)  更新右边界
   {
    r = m-1;
   }else{ 更新左边界
   l = m+1;
   res = m;  跳出循环后的返回
   }
 }
return res;
}
牛顿迭代法:
class Solution(object):
 def mySqurt(self,x):
  r = x
  while r*r > x:
   r = (r+ x/r) /2
  return r
36 字典树
 trie数据结构,最大限度查询
 空间换时间的办法。
 根节点不包含字符, 路径上对应的字符组成的
 字节不相同。
static final int ALPHTABLET_SIZE = 256
static class TrieNode{
 //有一个孩子节点数组
 TrieNode[] children = new TrieNode[ALPHTABLET_SIZE];
 // 是不是字符
 boolean isEndOfword = false;
 TriNode(){
 isEndOFWord = false; //不是字符
 for (int i =0;i < ALPHTABLET_SIZE; i++)
 {
  children[i] = NULL;  初始化孩子节点
 }

 }
}

public class Solution{
 Set<string> res = new HashSet<string>();
 public List<string> findWords(char[][] board,String[] words){
  创建一个字典树
  Trie trie = new Trie();
  把要匹配的字母添加到字典树中
  for (String word: words)
  {
   trie.insert(word);
  }
  字母表的维度和长度
  int m = board.lenght();
  int n = board[0].length();
  boolenn[][] visited = new boolean[m][n];
  for (int i = 0; i < m;i++)
   for (int j = 0;j < n;j++){
    dfs(board,visited,"",i,j,trie);
   }
 }
 return new ArrayList<string>(res)
}
public void dfs(char[][] board,boolean[][] visited,String str, int x,int y, Trie tire){
 if(x < 0 || x >= board.length || y < 0 || y>=board[0].lendgth) return ;
 如果被访问过
 if (visited[x][y]) return ;
 str +=board[x][y];
 是不是前缀
 if(!trie.startWith(str)) return;
 if(trie.seach(str)){
 res.add(str);
 }
 改变访问标志
 visited[x][y] = true;
 递归遍历左边
 dfs(board,visited,str,x-1,y,trie);
 递归调用右边
 dfs(board,visited,str,x+1,y,trie);
 递归调用下边
 dfs(board,visited,str,x,y-1,trie);
 递归调用上边
 dfs(board,visited,str,x,y+1,trie);
 visited[x][y] = false;
}
字典树
class TrieNode:
 def __init__(self):
  // type of  list
  self.children = [None] * ALPHTABLET_SIZE
  self.isEndofWord = False
方向数组
dx = [-1,1,0,0]
dy = [0,0,-1,1]
END_OF_WORD = "#"
class Solution(object):
   参数判断
 def findWords(self, board, words):
  if not board or not board[0]: return []
  if not words: return []
  装载结果
  self.result = set()
  Python中通过Key访问字典,当Key不存在时,会引发‘KeyError’异常。为了避免这种情况的发生,可以使用collections类中的defaultdict()方法来为字典提供默认值。
  空的字典
  字典树的节点
  root = collections.defaultdict();
  把
  for word in words:
   node = root
   for char in word:
    node = node.setdefault(char,collection.defaultdict())
   node[END_OF_WORD]=END_OF_WORD
  字母表的大小
  self.m self.n = len(board),len(board[0])
  for i in xrange(self.m):
   for j in xrange(self.n):
    是否是前缀
    if board[i][j] in root:
     self._dfs(board,i,j,"",root)
 def _dfs(self,board,i,j,cur_word,cur_dict)
  现在单词
  cur_word +=board[i][j]
  字典树的层
  cur_dict = cur_dict[board[i][j]]
  是不是已经找到单词
  if END_OF_WORD in cur_dict:
   self.result.add(cur_word)
    标记是否被访问过
  tmp, board[i][j] = board[i][j], '@'
  xrange() 函数用法与 range 完全相同,所不同的是生成的不是一个数组,而是一个生成器。
  for k in xrang(4):
   x,y = i + dx[k],j+dy[k]
   if 0 <=x<self.m and 0 <=y<=self.n
   and board[x][y]!='@' and board[x][y]
   in cur_dict:
    self._dfs(board,x,y,cur_word,cur_dict)
  恢复
  board[i][j] = tmp
class Trie(object):
 def __init__(self):
  self.root = {}
  self.end_of_word = "#"
 def insert(self,word):
  node = self.root
  for char in word:
   node = node.serdefault(char,{})
  node[self.end_of_word] = self.end_of_word
 def search(self,word):
  node = self.root
  for char in word:
   if char not in node:
    return false
   node = node[char]
  return self.end_of_word in node
 def startsWith(self,prefix):
  node = self.root
  for char in prefix:
   if char not in node:
    return false
   node = node[char]
  return True
字典树
class TrieNode{
 public char val
 public boolean isword;
 定义一个数组  每个节点都有26个孩子节点
 public TrieNode[] children = new TrieNode[26]
 public TrieNode() {}
 有参构造
 TrieNode(char c){
  TrieNode node = new TrieNode();
  node.val = c
 }
}
public class Trie{
 private TrieNode root
 public Trie(){
  根节点
  root = new TriedNode();
  root.val = "";

 }
 public void insert(String word){
  TrieNode ws = root;
  for(int i=0;i< word.length();i++)
  {
   char c = word.charAt(i);
   当c  不存在 创建一个新的
   if(ws.children[c-'a'] == null){
    ws.children[c-'a'] = new TriedNode(c);
   }
   ws = ws.children[c-'a'];
  }
  ws.isWord = true;
 }
 public boolean search(String word){
  TrieNode ws = root;
  //查找是否存在
  for(int i = 0;i< word.length;i++){
   char c = word.charAt(i);
   if(ws.children[c-'a'] == null) return false;
   ws = ws.children[c-'a'];
  }
  return ws.isword;
 }
 public boolean startWitch(String prefix)
 {
  TrieNode ws = root;
  for (int i =0;i< prefix.length();i++){
   char c = prefix.charAt(i);
   if (ws.children[c-'a'] == null) return false;
   ws = ws.children[c-'a'];
  }
  return true;
 }

}
39 位运算
 对二进制操作。
 & | ^ ~
 判断奇偶  X &1 == 1 or ==0
 最低为清零: x = x &(x-1)
40 统计bit1的个数
 1) x% 2 if ==1 count ++
  x = x>>1  时间复杂度 O(n)
 2) x = x&(x-1)
  while(x!=0){
  count ++;
  x = x&(x-1)
  }
def hammingweight(self,n):
 rst = 0
 mask = 1
 for i in range(32):
  if n & mask:
   rst +=1
  mask = mask >>1
 return rst
int hamingWeith(uint32_t n){
 int rst = 0;
 for(;n; n&=n-1)
 ++rst;
 return rst;
}

41 2的幂次方
  1) 循环模2
  2)位运算  x!=0 && x(x-1) ==0
  1) for i=0 ==>n count.bit(i)
  2)for (int i=0; i<n;i++)
  count[i] = count[i&(i-1)]+1

  bool isPowerOfTwo(int n){
  return n>0 && !(n&(n-1))
  }
def isPowerOfTwo(self,n):
 return n>0 and not (n&(n-1))
vector<int> countBits(int num){
 定义要给数组大小位 nums+1 初始值为0
 vector<int> bits(nums+1,0);
 for (int i =1; i<=nums; i++){
 地推
  bits[i] += bits[i&(i-1)] +1;
 }
return bits;
}
原文地址:https://www.cnblogs.com/countryboy666/p/11521690.html