Chapter 68 Indeed

68.1 Unrolled Linked List

Unrolled_linked_lists.png

Unrolled_linked_lists.png

https://goo.gl/mg35Ae

#ifndef APPLECPP_UNROLLEDLL_H
#define APPLECPP_UNROLLEDLL_H
#include <henry.h>
namespace _indeed_ULL{
  struct node{
    char v[5];
    int num_char;
    node* next=0;
  };// null ended single linked list
  struct unrolledLL{
    unrolledLL():head(0),num_char(0){}
    node* head;
    int num_char;
    char get(int i){// index
      if(i<0 or i>=num_char){return '\0';}
      node* c=head;
      int start=0;// the first char's index in the node
      while(c){ // index+length is index
        if(i<=start+c->num_char and i>=start){
          return c->v[i-start];
        }else{
          start+=c->num_char;
        }
        c=c->next;
      }
      return '\0';
    }
    //Insert需要考虑
    //1.普通插进去.
    //2.插入的node满了,要在后面加个node.
    //3.插入的node是空的,那就要在尾巴上加个新node.
    //还需要考虑每个node的len,以及totalLen的长度变化.
    bool insert(char ch, int i){
      if(i<0 or i>num_char) return false;
      node* cur=head;
      int start=0; // start index of every block
      while(cur){
        if(i>=start and i<start+cur->num_char){ // half open BUG
          // BUG
          if(cur->num_char==5){ // node is full
            node* nn=new node();
            nn->v[0]=cur->v[4]; ////BUG
            nn->num_char=1;
            nn->next=cur->next, cur->next=nn;
            for(int j=4;j>i-start;j--) cur->v[j]=cur->v[j-1];
            cur->v[i-start]=ch;
          }else{ // spacious
            // right shift char in [i-start, cur->num_char-1]
            for(int j=cur->num_char-1;j>i-start;j--) cur->v[j] = cur->v[j-1];
            cur->v[i-start]=ch;
            cur->num_char++;
          }
          num_char++;
          return true;
        }else{
          start+=cur->num_char; // index + current block length = index of next block
        }
        cur=cur->next;
      } //at this point, cur must be null now
      //这里又分两种情况,一种是head is null, another case is all node are full
      //BUG
      node* n=new node();
      n->num_char=1, num_char++;
      n->v[0]=ch;
      if(!head) head=n;
      else{ // find the last full node
        auto tail=head;
        while(tail->next) tail=tail->next;
        tail->next=n;
      }
      return true;
    }
    //类似insert,先考虑清楚delete的情况
    //1.普通的去掉一个node里面的点.2.去掉node之后,这个点空了,那就把点删掉.
    //也要考虑每个node里面长度的变化.
    bool del(int i){
      if(i<0 or i>=num_char) return false;
      node d;
      d.next=head;
      node* c=head, *prev=&d;
      prev->next=c;
      int start=0;
      while(c){
        if(start<=i and i<start+c->num_char){ // BUG
          if(c->num_char==1){
            prev->next= c->next;
          }else{
            // left shift chars [i+1-start, c->num_char-1]
            for(int j=i-start+1;j<c->num_char;j++) c->v[j];
          }
          c->num_char--, num_char--;
          break;
        }
        start+=c->num_char;
        c=c->next, prev=prev->next;
      }
      head = d.next; // old head could be removed!
    }
  };
  void test(){
    unrolledLL u;
    for (int i = 0; i < 38; ++i) {
      u.insert(char('a'+i%26), i);
    }
    assert(u.get(-1)==0);
    assert(u.get(26)=='a');
    u.del(25);
    assert(u.get(25)=='a');
  }
};
#endif //APPLECPP_UNROLLEDLL_H

68.2 Roll Dice

扔N次就有6^N种不同的组合,虽然这些组合中一定有sum相同的. 总的个数一定是6^N. 然后要求这些路径中和为target的路径的个数X. 那么结果就是X/N.

这样就变成了求Permutation sum的问题.

Algo 1 - Naive

This showcase How to do reference in JAVA int counter

Algo 2 - DFS Memo

Algo 3 - DP

dp[i][j] - 扔i次和为j的路径数 等于 扔i-1次和为j-[1|2|3|4|5|6]的路径数的和.

如果i<j, dp[i][j]肯定为0,因为dice点数至少为1点,所以roll i次,和一定大于等于i. 这是一个upper triangular matrix.

int[roll_num+1][target+1]要加1是因为java的array的index是0-based的.

68.3 Git Commit

Given a git commit (wiki:…), each commit has an id. Find all the commits that we have.

  • Follow Up

找到两个commit的最近公共parent commit.而且被要求优化,因为是follow up,所以到时候时间肯定 剩下不多,面试时候要直接出最优解.

题目内容:

给出一个Git的commit,找出所有的parents.每个节点都有一个或多个parent. 另外每个commit都是带着ID的.就是没太懂它是输出所有的commit还是要求逐层打印. 第二题就是找到两个commit的公共祖先. Git的commit是可以分叉的也可以合并,所以这题其实是个图. 想来真是好久没弄github了. 其实就是BFS和双向BFS,注意好对复杂度的分析吧.优化就是双向BFS吧.

68.4 Normalized Title

Given a rawTitle, and a list(or array) of clean titles. For each clean title, the raw title can get a “match point”. For example, if raw title is “senior software engineer” and clean titles are “software engineer” and “mechanical engineer”, the “match point” will be 2 and 1. In this case we return “software engineer” because it has higher “match point”.