算法与数据结构最优解实例总结

本文深入探讨了栈、队列、链表、二叉树等数据结构的关键操作与应用,如猫狗队列、汉诺塔问题、链表反转、约瑟夫问题等,并详细解析了二叉树的最大搜索子树、平衡性判断、层序遍历等问题,同时涵盖了递归、动态规划、字符串处理、大数据处理、位操作等高级算法技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.栈与队列

1.1 猫狗队列

      新增队列对象 class PetEnterQueue{    Pet pet,  int  count    }     count 为时间戳

      ----》class DogCatQueue{   queue<PetEnterQueue > dog,queue<PetEnterQueue > dog cat, int count    }

1.2 汉诺塔 

      process(num,lef,middle,right,from,to){

       process(num-1,left, midle.right,from,to)

       left to middle

       process(num-1,left, midle.right,to,from)  

      middle  to  right

       process(num-1,left, midle.right,from,to)

     }

2.链表问题

反转单向链表: tmp =  cur.next  ->    cur.next = pre   - >   pre = cur   -> cur = tmp 

约瑟夫问题  :Node head , int m     -  > last = head

                     last = last.next   但是  ++n  ==  m    ---->   last.next = head.next (跳过head)

                     head = last .next  新头节点(无论是跳过还是不跳过,都是last.next)。   

3.二叉树问题

3.1 最大搜索二叉子树 --后序遍历

public Node biggestSubBST(node head){

    int [] record = new int[3];

    return posorder(head , record); 

}

posorder( head ,record){

if head == NULL{

record[0]=0

record[1] =max

record[2] = min

}

value = head.value

lBST = posorder(left,record)

lsize = record[0]

lmin = record[1]

lmax = record[2]

rBST = posorder(right,record)

rsize = record[0]

rmin = record[1]

rmax = record[2]

record[1] = min(lmin,value)

record[2] =  max(rmax,value)

if ( rmin > value && lmax <value){

record = lsize +rsize +1

return head

}

3.2  层打印: queue 不断push 。

3.3 平衡二叉树:左右子树高度差

getheight ( node , level, bool  res)

   if node =NULL

               return level

  getheight(node.left,level+1,res)

gethegith(node.right,level+1.res)

if abs(left -right) >1   :     res = false

return   max(left,right)

}

3.4 完全二叉树:层遍历,若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

lnode ==null && rnode != null     return false

lnode !=null  queue.push(lnode)

rnode !=null queue.push(rnode)  else leaf = true

4 递归和动态规划

4.1  fn  { return  f(n-1) +  f(n-2)}

4.2  最小路径   new 一个  d[i][j] = min(d[i-1][j] + d[i][j-1]) + m[i][j]

4.3最长公共子序列:

d[i][j]  即str1[0~i]跟str2[0~j]的最长

d[i][j] = max(d[i-1][j], d[i][j-1])

if str1[i] = str2[j]        d[i][j] = max[dp[i-1][j-1]+1 , d[i][j]]

4.4最长公共子串  if(str1[i]==str2[j])   d[i][j] = d[i-1][j-1] + 1

4.5  n 皇后问题

     int[]  record  =  new int[n]

      process (0 , record ,n )

public   process( i ,record ,n ){

for j = 0  ;j <n ;j++{

if (isValid(i,j,record )){

      process( i+1,record,n) //  i+1 是因为再下一行的意思,j+1在j全都递归回来之后,再+1

           }

      }

}

is Valid( i , j ,record){

for k <i ;i++

      if (record[k]==j or   abs(k-i) ==abs(record[k] - j)  )      return false     //同一列  ,或同一斜线    a-i  == b-j

return true 

}

 

5.字符串问题

变行词: 用map来count  str1 ,再遍历str 不断 map--  ,如果有负则返回

数字字串求和:  num = num*10 +cur        ->  res = res + num  and num =0 (及下次如果是字母,res + 0)

字符串转整数  :  判断是否大于   2*32 / 10 或者  等于 2*32 /10 但是  后一位 > 2*32 %10 考虑负数则很有趣

-2147483648   2147483647 则转为负数来处理。

字符串匹配问题:


6. 大数据与空间限制

     2GB 从20亿个整数中找到次数最多的。

     2^ 32 = 4,294,967,296     = 43亿

     假设每个数字都不同 ,则hash  key用32位能解决。假设1个数字20亿,也能用32位解决。也就是说一条记录要4B*2 = 8B

     8B *1亿   <  8亿B   =0.8GB  ,所以  20 *0.8 =16GB    所以分成8份即可,每份 大约就2gb内存。是否需要考虑hash的效果,所以取16份?

7. 位操作

     swap(a,b)  ->   a = a^b      b = b^a       a = a^b

                         获取不同      与b不同就是 a(交换得到a)        与 b(此时已经是a,再次取反)不同就是a 

8.数组和矩阵

 求最短通路

1 1 1  1  1

1 0 1  0   1

1  1 1  0  1

0  0  0  0  1

关键在于两个队列来记录走通的位置,然后不断pop出来,用队列是因为要宽度优先。比如 (1,3)这个点肯定是直接往右最快,然后另一条回路到打此点时,发现已经被标记则放弃,这是因为宽度优先,保证了被标记的点必定之前的路径不大于此时的路径。

while(){

1.walkup

2.walk down

3.walk left

4. walk right

}

walk(int pre ,int toR,int toC,int rect [][],int map[][], queR,queC){

              到达目的地或者 rect [toR][toC] ==0 或者 Map[][]!=0

                       return

              map[][] = pre +1 

             queR.add(toR)

             queC.add(toC)

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值