7人加入学习
(0人评价)
CS算法集训班
价格 $99,999美元
该课程属于 2023.7.9 CS课程 请加入后再学习
  • 进阶链表
  • 进阶树
  • 进阶图

 

  • 进阶链表

双向链表,

例题 430  .   dfs即可

 

异或链表

 

  • 进阶树

segement  tree

,  节点里面能存储区间

 

303.  问题在于如果调用很多次怎么办,可以用新的存储空间来存储,

 

Trie: 字典树

 

平衡树

 

N 叉树

 

B树 

 

红黑树

[展开全文]

maimimum moving avarage:

 

maimimum moving max:

:可以一用heap么。不可以,因为不知道pop的是不是头

:可以用sorted stack

:思路:,squential,,,每到一个ele时,有可能时后面max,所以先判断前面《的话,删掉然后加上本个ele,》的话直接加上,因为stack村的是有可能是max的东西。  如果move 后out of window,先删除对应操作,这样stack顶永远是max当前window。   

这样用的就是deque,或者double linklist,

out of window 的时候要注意判断头部是不是out? index stack:记录index,,然后j-i>=k,就是out  of window

 

dfs  stack的模板:

DFS(s,g):

   stack s,

   end constraint g,

  initilaize s:  push first node to s and visited hashet, parent hashmap.

  while(stack not empty:){

            pop node;

           if(cur==G) return 

           for (each neighburs not visited){

                 add neighvbut to visited

                add cur as parent of n

               push n onto stack

 

 

 

 

 

  • 图论

1.Maze  ,  2D array,  赵路径

例题:maze II。

 

使用的三个数据结构:“hash set, bisited”"hahmap,path"  "stack或者queue"

 

C++中可以用vector<bool>也可以待变visited

看题目要求是不是要path,如果去找neighbour,  

 

Maze中可以用i,j+-1,或者用一个direction矩阵代表更多方向,然后for循环去迭代方向

 

2. 2D array   all points

 

flood fill.    填色

 

思路:single point dfs/bfs都可以,  时间complexity都一样  |V|+|E|.

dfs  的recursion的代码量简洁。

 

 

例题:number of island。

思路,for矩阵,然后dfs开始,碰到1就边0,然后整体计算number

,all points 的dfs就是for single point的dfs

   

3。 friend circles,  邻接矩阵,像但由于是一个对角线的all points

可以用dfs找path,如果能有一条path,说明一个circle,没有说明第二个circle

for  i  是代表人,利用visted代表circle,dfs之后count++就是circle的数量

 

 

4.  例题:pacific atlantic water flow.

还可以用dp的结果,避免重复计算

,可以:aLL points+DP

DP里面不同的值来代表不同的意思

还要回溯,底部true,回溯回去也要true,一路的retrun

selected point:

 

 

5. non 2D array   

 

例题:word ladder

 

思路:每个word是一个vertex,

可以用stack。

要解决的问题:neighbour,hashset,hahmap,start

这里难点在于如何判断neighbour,

 

思路,可以对于当前单词进行每个位置的字母改变,然后find 字典里是否有出现。

 

BFS可以求最短路径

[展开全文]
  • sliding window

属于2 pointer的子集,都是从前往后走

例题:remove duplicated from sorted array

思路:end往后走直到最后一个different。然后start是第一个diff, 所以in place的算法是吧dif的ele move到start,start+1.

so  start: is the first distinct的position

end是来判断,if dif的话就跟start换位置,if equal则end+1

 

思路:hashset可以用,o(n)和o(n)

duplicates可以用hashtable

例题:如果diuplicate的出现次数k,

 

思路:那么判断start的前面有几个,或者判断end-2和end是否一样或者j-i>=2

 

例题:remove element:(inplace)

start是第一个1的位置,然后end是non-1,然后swap,然后i+1,j都要加1,

所以一开始的start是先找到对应1(要先for),也可以不用

for(int i,j;i<len&j<len;j+1){ if (nums[i]!=1) start+=1}

 

例题:  maximum average subarray.

start 是maxim的start。  end++,一个global max,然后更新start。end往前数,然后maximum可以减去头+尾。单个for就可以

思路:也可以累加,然后减去前面k的元素当前的和,然后就是当前的k个和

例题:sliding  window 3

 

思路:rolling hash,利用hashcode计算,而且可以偷懒,类似于上面的去头加尾

 

 

例题:subarrayproduct less than k

start和end,end先移动到最小不满足,然后startmove到满足,这其中每一个sub都是满足的

但是计算的是number,而不是每一个subarray,所以j-i+1是多的validwindow,计算

 

例题: sliding window 2:

 

例题:minimum size subarray sum

 

思路:start,end中间的和,global存储当前的最短,if sum>k,则start+1. 然后继续end+1判断。  start<end肯定

for内嵌while (i),但是i和j相对独立,所以时间复杂度是O(n)

 

例题:sliding window IV

 

例题:longest substring without repeating characters

 

 

区分subsequence和esubarray

遇到duplicate,repeateing,exist,unique都可以用hashmap来解决

 

[展开全文]

例题:47 permutation 2:

input 有重复,有一个i-1的non-visited判断

 

例题:131,palindrome  partition,实际上是个组合问题,可以用组合模板,先判断前面的substring的是不是palidrome,然后对于后面的substring进行dfs。

优化:dp的memorization将已经pali的存起来

 

例题:44  .1h

 

  • Trie字典树

add and search words

复杂度:O(M)就是最长单词长度,space复杂度:字母表长度*key——length(比如说一个char)*key个数

例题:add and search words

要在对应word的结尾标记一个证明是一个word。

trie是用hashmap实现的

 

例题:auto-complete system: 

 

例题:word search 2.   212.因为input是字符串,所以可以用trie来节省一部分时间,

 

回溯的时候要标记回来,visited.true. dfs(),

visited=false

 

 

trie:

class TrieNode{TrieNode[] next= new TriNode[26],   String word},要标记当前是不是一个word,这就是flag,可以灵活变通,也可以把当前的词存进去

 

 

[展开全文]

notability

例题329.1h17min

 

 

valid  括号问题 例题

背包问题

例题:301

 

DFS,去重复剪纸

BFS?

 

经典:number of island

 

例题:827

making a large island

复杂度:n2,当前点

例题:312

 

例题:  子问题互相影响,dp[i][k-1]

dp[k+1][j],定义是两边不能炸

 

[展开全文]
  • DP 问题

算法原理:

  1. 可以表示成离散状态的相并列和矩阵形式,每个元素代表子问题最优解。子问题不依赖更大的子问题
  2. 最终最优解是多个子问题的最优解来确定(多个状态同时),如果一个状态就是greedy
  3. index最小的子问题解已知
  4. 状态转移方程
  5. 两个方向:“top-down”来分析问题然后bottom-up来优化问题/
  6. top-down一般用递归来解决,bottome-up一般是iteration来解决

算法复杂度:

  1. time complexity:某些子问题解应用不止一次,所以memorizaition来节省空间
  2. space complexity:“某些解只用几次,因此不必在存储”

例题:longest in creaseing subsquence 

 

greedy,使用的话要证明一下多个状态可以用一个状态解释

 

例题:  wiggle subsqueece

 

例题:背包问题

 

例题:96  unique binary search tree

numtrees(n-2)*num(1)+.... numtree(1)*nums(n-2), 左右子树排列数,因为bst型确定了,数也就确定了

 

例题:括号问题,和上面类似

 

 

例题:edit 。。。。  状态转移方程。 1h23 min

例题: pattern  matching  :44  wildcard mathcing

 

 

例题:permutations for di sequence

[展开全文]
  • DFS&BFS

tree上边的tranversla和divi&&conquer就是DFS

 

 

BFS,binarty tree level-order tranversal一层一层的走就是

图和tree: tree,没有cyce,dfs不会重复,图可能有环,可能死循环如果不记录的话

 

 

where you can search:tree,graph,Combination of Linear structures(array,string, number)

 

LTC 102: binary tree level order Traversal

.BFS用到了queue,FIFO 

stack可以实现DFS,不过先right child然后leftchild,这样可以保证print先left在右,因为stack的先入后出

BFS有模板

 

1h27  例题: 200 number_of island,可以使用DFS,或者queue的BFS

 

1h40  例题:78subsets。  sort,避免重复的number。

使用递归实现combination,复杂度exponential

  • combinatoin

 

所有combination的题目有一个模板2h06

先sort!!!

result。add中 new arraylist(subset)?deep copy

startindex看看是否可以服用,可以复用,i不变否则i+1

例题:90subset2.  2h09, 加上一句判断现在和前者是否一样,并且不能越界。

这样就不用单独新建一个vecotr去重了

 

例题:39  combination sum 

40Com sum2.  右duplicate

216  com sum3.  size=k的sum=target

 

helper必须传的参数,startindex,原始array,每层的solution,总的result

 

 

  • 排列,有顺序有模板

46.permutation。2h31min

所有的数都要被选

permutation 2例题,

 

 

 

[展开全文]
  • 贪心算法和DP

贪心算法:

定义:选择的贪心策略必须具有无后效应,寄某个状态之前的过程不会影响以后的状态,只与当前状态有关。

需要判断一下当前的最优解是不是最终的最优解。

 

最优子结构:当问题的最优解包含子问题的最优解的时候

 

局限性:

  1. 不能保证最后的结果一定是最佳的。
  2. 不能有来求最大或最小解问题
  3. 只能求满足某些约束条件的可行解的范围

上节课的dikistra,prim,krukal算法都是贪心算法。

上述算法也都有一些限制条件,就是为了约束最后的最优解的

 

大部分例题都能有DP解

例题:455: assign cookies。40min

 小给小,大给大,可以sort后双指针遍历人和饼干,

122:Best time to but and Sell stockII

53:

134:gas

55: jump game。 只是求哪里开始可以完成目的可以贪心,但是求最小步骤不能用贪心算法。

 

总结:贪心算法主要是针对一维问题,不需要独立,DP是前后有关系,需要记录

 

 

  • 动态规划

讲一个问题拆分成几个子问题,分别求解子问题。

步骤:

  1. 划分阶段,有序或者可排序(无后序性)
  2. 选择状态(无后行)
  3. 确定状态转移方程(根据上一阶段状态到处本阶段方程),确定了决策,状态转移方程也就出来了
  4. 写出规划方程,只需要写iterative的,不要写recursive。

 

重点:初始状态,和状态转移方程。

基本要素:

  1. 重叠子问题:用到之前很多数的结果,比如fibncci。
  2. 最优子结构
  3. 无后效性,保证之前的状态都已经更新完了才能拿来用,不能够用完这个数据后这个数据还在更新。 循环的顺序和倒序等等。

 

要学会问题归类:尤其是DP问题。例如二维DP,写两层循环。。

一般是最大利润或者最小误差等

例题:198:house robber。

初始条件:最大财务=0.

状态转移方程:每次到房子的时候利用和前面房子的关系,限制条件:不能连续抢。一般来说最后求最大财务数,每一步也要求最大财务书。

对每个房子状态两个:抢或者不抢,强的话:i-2的财务+当前财务。 不强的话:i-1的财务。

一般不用矩阵,因为只跟前一个或两个有关系。直接用几个变量表示就行。 矩阵的话一般是跟前n个有关。

 

 

  • 卖股票系列:

状态转移,当前状态买,卖,不做。

初始值:一般来说是最大利润,

然后加上边界调节。有可能要加矩阵的维度,eg.cooldown

例题集合:1h24min

121.。。。。。。

 

 

贪心算法和动态规划的关系:

相同点

  1. 都是一种递推算法
  2. 均有局部最优解来推导全局最优解

 

不同点:

  • 贪心算法(了解即可,自己做的时候看懂就好)因为要证明最优解还需要时间而且可能会错

每一步的贪心决策都无法改变,之前的最优解不做保留,每一步的最优解一定包括上一步的最优解

 

  • 动态规划

(只要掌握动态规划就好,)

 

 

  • 区间调度问题

最多区间调度问题,可以通过贪心算法1h48min

最大区间:只能用DP

 

例题:56 merge intervals. 2h07min

435

452

252

715 Hard

 

背包问题(leetcode 一般只有01背包和完全背包问题)。

2h17min,记得V的循环顺序

 

lintcode有很多例题

 

 

[展开全文]

大公司更偏向算法和基础知识掌握,比如刷题更针对大公司。 算法和数据结构。 bar:focus 在解题能力,没有system-design要求对刚毕业的人。45分钟解答出一到两道1-2难度的题、有可能有hard。 

大公司即便对计算机没有极大的要求也可以通过面试进去。

小公司要求项目能力,额外学一些java在工业界,安卓等上面的应用。

 

Sublime text, VS code build java。IDE有联想功能可能更方便

  • Java 面对对象的编程语言,类似python

分为:object, method, class

 

import java.utils.*;

import java.io.*;

pubilc class Helloworld {

      public  main( String[] args ) {

System.out.print.....

     }

}

 

 

 

  1. object

String s;    s=new String();   合并成一:String s=new String("Hello")

例子: String s2=s 指向同一个object

s2=new String(s);  这两个不一样的object,东西一样。

s2=s.toUppercase();  String s3= s2.concat("!!"); ===s3=s2+"!!"  s3和s2不一样的object。s2创造了新的指针,没有改变原来的string。 但这个只是对string成立的,即要想改变string object,只需要create 一个新的 string就行,

  • Class

class human{

    pubilc int age;

    pubilc void introduce()  {  print}  这是method

    oublic void copy( Human ori){         

                         age=orig.age}

}

Human amada= new Human();创造一个object

amanda.age=6;  赋值

amade.introduce() ;call method

Human mike= new Human() ; 新的object

mike.copy(amand); 这里mike的变量和amaenda一样

 

  • constructors

可以自己定义,也有默认,因为上面就是没有外部赋值给一个内部元素,防止崩溃:

     public human(int x, string name){

  age=x; y=name  }

但是注意:Human amada= new Human();这样会报错,和定义的constructor不一样

  • this, 充当的指针

class human{

    pubilc int age;

   pubilc human(int givenage){  this.age=givenage, this.name='skkkk'}                                       this是optional

   pubilc void chaneg(int age,){

    this.age=age}这里this不能省略因为要不然没用age=age

}

  • static

可以在不同的objects里面share同样的值

eg.   class human{

       pubilc static num;

      public  human(){

        num++}这样可以用的统计object数量,因为每个object都有同样的值

       pubilc static void printhume(){

        num} static method不能pass object,因为这可能导致不同的object的static变量然后出错

}

  • variable的lifetime

local: method里面就是method运行完就消失。

instance :非静态:就是只要amanda这个object还在,他就在

static:只要program在运行就一直在,所以不同的object可以share

  • primitive type variable

不是reference to object,例如 int, long, float, 怎么创建: “6”,“3.4”, “true”

object create: new 

object define: class definition

            initialize: constructor

            use: method

例如 string 是一个object,可以 String name="hello";   name ="world"指向了另一个object。

这是java 内置的, 一般string不用写 String name= new String{"hellp"}

  •          java library

Math class.

Integer class.//convert a string to an integer.   注意 Integer.conv("3.14")会报错

  • boolean

&&, ! , 等等操作

x= 3==5 可以直接判断赋值

boolean pass =score <60

if (pass){} else{}

也可以if (score >=60){}更简洁

简介的表达形式:a= x>y ? max(x,z) : max(y,z)

  • Switch-case

switch (month){  

case 2:

      a=2;  break;

case 4:

case 6:

default: days=2;  break;

}

  • do loop

 do {}  while()起码会run一次,while有可能一次不run

  • for

for (initialize; condition; next) {},next 可以省略

  • array

fixed number , z在create的时候就确定了

char[] c;  // reference to an array

c=new char[4];  //construct and array

c[1]='b';//赋值

小窍门: 判断n的平方根和d比较: d*d <=n因为开平方比较耗资源

  • multi-dimensional array

two dimensional array is an array of references to arrays. 第一层里面存的是内部array的指针

int[][] pt= new [n][]    这样的话内部矩阵可以不同长度  例如帕斯卡三角, 当然内部长度也可以直接定义

for (int i=0; i<n; i++){

                 pt[i]=new int[i+1]   // 内部 

}

更多array declarations: 

human[] b={a, mike, new human("me")}

int[][] c= {{7,4,3},{3,3,x},{x+y}}

d= new int[] {3,7}

     下面这些都是declaration:没有construct

int[] a,c,b ;/// a,b,c all reference array,不是object

int a[], b,c[][] /// a is 1D,b is not a reference/array

int[]  a,b[]/// a is a reference to a 1 D array, b reference a 2D array 很逆天

 

[展开全文]
shaning · 2023-10-20 · Java 1 0

授课教师

课程特色

视频(25)

学员动态

Bianyw 加入学习
shjm 加入学习
YanHuang 加入学习
duoduo99 加入学习
wuhaojia 加入学习