查看: 3940| 回复: 18
跳转到指定楼层
上一主题 下一主题
收起左侧

[高频题] 数组Snapshot

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
您好!
本帖隐藏的内容需要积分高于 150 才可浏览
您当前积分为 0。
使用VIP即刻解锁阅读权限或查看其他获取积分的方式
游客,您好!
本帖隐藏的内容需要积分高于 150 才可浏览
您当前积分为 0。
VIP即刻解锁阅读权限 或 查看其他获取积分的方式
Unlock interview details and practice with AI
Curated Interview Questions from Top Companies


评分

参与人数 3大米 +10 收起 理由
阿满 + 2 给你点个赞!
helloteacha + 5 很有用的信息!看到很多次就不知道原题
西风瘦马1912 + 3 很有用的信息!

查看全部评分


上一篇:segment tree有必要掌握吗?
下一篇:问一道DP,真不会orz
推荐
kaipeng21 2019-3-18 07:59:37 | 只看该作者
全局:
第二种

您好!
本帖隐藏的内容需要积分高于 220 才可浏览
您当前积分为 0。
使用VIP即刻解锁阅读权限或查看其他获取积分的方式
游客,您好!
本帖隐藏的内容需要积分高于 220 才可浏览
您当前积分为 0。
VIP即刻解锁阅读权限 或 查看其他获取积分的方式
Unlock interview details and practice with AI
Curated Interview Questions from Top Companies
回复

使用道具 举报

推荐
testwe 2019-4-18 01:32:21 | 只看该作者
全局:
简单的写了下数组的。 基本思想是:
  • 维护一个version num,TakeSnapshot时加1
  • 数组的每个元素是一个{since_version, value} 的vector (保存的其实是the value since a version的信息)
  • Get,O(log(那个元素不同版本的个数)),二分查找到想要的since_version即可,我这里用的是upper_bound的结果减1
  • Set,O(1)。看看那个位置最新的version,如果和当前version相等,直接覆盖;否则append


  1. #include <algorithm>
  2. #include <cassert>
  3. #include <vector>

  4. using namespace std;

  5. template <typename ValueType>
  6. class VersionedArray {
  7. public:
  8.   using Version = size_t;

  9.   // default_val is the default value when an element doesn't exist.
  10.   explicit VersionedArray(size_t size, ValueType default_val)
  11.       : v_(size), default_val_(default_val) {}

  12.   void Set(size_t pos, ValueType val) {
  13.     assert(pos < v_.size());

  14.     if (v_[pos].empty() || v_[pos].back().first != ver_) {
  15.       v_[pos].push_back({ver_, val});
  16.     } else {
  17.       v_[pos].back().second = val;
  18.     }
  19.   }

  20.   int Get(size_t pos, Version ver) {
  21.     assert(pos < v_.size());
  22.     if (v_[pos].empty()) {
  23.       return default_val_;
  24.     }

  25.     // Find a version > ver, then the previous version is what we want.
  26.     auto it = upper_bound(
  27.         v_[pos].begin(), v_[pos].end(), make_pair(ver, -1),
  28.         [](const pair<Version, int>& v1, const pair<Version, int>& v2) {
  29.           return v1.first < v2.first;
  30.         });
  31.     if (it == v_[pos].begin()) {
  32.       return default_val_;
  33.     }
  34.     return prev(it)->second;
  35.   }

  36.   void TakeSnapshot() { ver_++; }

  37.   Version LatestVersion() const { return ver_; }

  38. private:
  39.   vector<vector<pair<Version, ValueType>>> v_;
  40.   Version ver_ = 0;
  41.   const ValueType default_val_;  // Default value when an element doesn't exist.
  42. };

  43. int main(int, char*[]) {
  44.   constexpr int NOT_FOUND = numeric_limits<int>::min();
  45.   VersionedArray<int> va(10, NOT_FOUND);
  46.   va.Set(0, 0);
  47.   assert(va.Get(0, va.LatestVersion()) == 0);
  48.   assert(va.Get(1, va.LatestVersion()) == NOT_FOUND);

  49.   va.TakeSnapshot();  // Now latest version is 1

  50.   va.Set(0, 10);
  51.   va.Set(1, 11);
  52.   va.Set(1, 111);

  53.   assert(va.Get(0, 0) == 0);
  54.   assert(va.Get(0, 1) == 10);
  55.   assert(va.Get(1, 0) == NOT_FOUND);
  56.   assert(va.Get(1, 1) == 111);

  57.   va.Set(1, 1111);

  58.   va.TakeSnapshot();  // Now latest version is 2
  59.   va.TakeSnapshot();  // Now latest version is 3
  60.   va.TakeSnapshot();  // Now latest version is 4
  61.   assert(va.Get(0, 0) == 0);
  62.   assert(va.Get(0, 1) == 10);
  63.   assert(va.Get(0, 2) == 10);
  64.   assert(va.Get(0, 3) == 10);
  65.   assert(va.Get(0, 4) == 10);

  66.   assert(va.Get(1, 0) == NOT_FOUND);
  67.   assert(va.Get(1, 1) == 1111);
  68.   assert(va.Get(1, 2) == 1111);
  69.   assert(va.Get(1, 3) == 1111);
  70.   assert(va.Get(1, 4) == 1111);

  71.   return 0;
  72. }
复制代码






补充内容 (2019-4-18 01:34):
Followup的map,和数组相比,基本类似

补充内容 (2019-4-18 01:35):
刚才补充了一句话,原来能高亮的代码排版全乱了。麻烦版主看到了帮忙修改一下代码的格式。

评分

参与人数 1大米 +1 收起 理由
xlblue + 1 给你点个赞!

查看全部评分

回复

使用道具 举报

全局:
请问楼主,输入的是什么东西?不同的version是什么意思?
回复

使用道具 举报

🔗
 楼主| 14417335 2019-3-3 21:48:57 | 只看该作者
全局:
西风瘦马1912 发表于 2019-3-3 10:06
请问楼主,输入的是什么东西?不同的version是什么意思?

举个例子吧:
您好!
本帖隐藏的内容需要积分高于 150 才可浏览
您当前积分为 0。
使用VIP即刻解锁阅读权限或查看其他获取积分的方式
游客,您好!
本帖隐藏的内容需要积分高于 150 才可浏览
您当前积分为 0。
VIP即刻解锁阅读权限 或 查看其他获取积分的方式
Unlock interview details and practice with AI
Curated Interview Questions from Top Companies
回复

使用道具 举报

🔗
Warald 2019-3-8 06:17:53 | 只看该作者
全局:
关于双倍积分奖励算法题和系统设计题讨论的决定:

我们:
1. 希望能看到干货讨论;
2. 希望能看到好的代码(web端高级发帖模式下,@ 朋友右边的<> 可以选择多种代码)

版主 @14417335 负责审核加分,也请大家给好的回复加分 + 顶。
大家给30,我会跟进奖励30,double之;
大家给100,我也会跟进奖励100,double之。

很理解大家写代码、调试、写思路分析,很花时间。对于特别好的回复,还会有额外加分。

欢迎大家拿出好的题目讨论,选中了我会全站置顶。哪位同学起了好的题目/帖子,激发了干货讨论,也会获得一定的积分奖励。

欢迎大家踊跃参与。看到好的回复,也请大家顶一下,作为对别人积极参与讨论、热心分享的认可和鼓励。
其他可以获得双倍积分的题目:

在刷题版里选择高频题标签,链接:
https://www.1point3acres.com/bbs/forum.php?mod=forumdisplay&fid=84&filter=typeid&typeid=1019大家看到LC没有的高频题,也请贴到刷题版里,又有大米又有赞。对于学弟学妹们也是功劳一件。举手之劳。谢谢大家的参与。



回复

使用道具 举报

🔗
 楼主| 14417335 2019-3-11 01:10:04 | 只看该作者
全局:
增加一个followup,Snapshot Map

您好!
本帖隐藏的内容需要积分高于 150 才可浏览
您当前积分为 0。
使用VIP即刻解锁阅读权限或查看其他获取积分的方式
游客,您好!
本帖隐藏的内容需要积分高于 150 才可浏览
您当前积分为 0。
VIP即刻解锁阅读权限 或 查看其他获取积分的方式
Unlock interview details and practice with AI
Curated Interview Questions from Top Companies
回复

使用道具 举报

🔗
magicsets 2019-3-11 14:55:19 | 只看该作者
全局:
关于Snapshot Map我写了一份参考代码:

  1. import java.util.ArrayList;
  2. import java.util.Collections;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;

  6. public class Main {  
  7.   public static void main(String[] args) {
  8.     SnapshottableMap map = new SnapshottableMap();
  9.     Snapshot s0 = map.createSnapshot();
  10.    
  11.     map.put("name", "John");
  12.     map.put("country", "UK");
  13.     Snapshot s1 = map.createSnapshot();
  14.      
  15.     Assert(s1.get("name").equals("John"));
  16.     Assert(s1.get("country").equals("UK"));
  17.      
  18.     map.put("name", "Marta");
  19.     Snapshot s2 = map.createSnapshot();
  20.      
  21.     Assert(s2.get("name").equals("Marta"));
  22.     Assert(s2.get("country").equals("UK"));
  23.     Assert(s1.get("name").equals("John"));   

  24.     Assert(s0.get("name") == null);
  25.    
  26.     map.put("label", "AAA");
  27.     map.put("label", "BBB");
  28.     Snapshot s3 = map.createSnapshot();
  29.     Assert(s3.get("label").equals("BBB"));
  30.    
  31.     System.out.println("--------\n" + s1.toDebugString() + "--------\n");
  32.     // --------
  33.     // country: UK
  34.     // name: John
  35.     // --------
  36.    
  37.     System.out.println("--------\n" + s2.toDebugString() + "--------\n");
  38.     // --------
  39.     // country: UK
  40.     // name: Marta
  41.     // --------
  42.    
  43.     System.out.println("--------\n" + s3.toDebugString() + "--------\n");
  44.     // --------
  45.     // country: UK
  46.     // name: Marta
  47.     // label: BBB
  48.     // --------
  49.   }

  50.   private static void Assert(boolean value) {
  51.     if (!value) {
  52.       throw new RuntimeException("");
  53.     }
  54.   }
  55. }

  56. // Snapshot只存version number和主map的引用
  57. class Snapshot {
  58.   private int snapshotVersion;  
  59.   private SnapshottableMap map;

  60.   public Snapshot(int version, SnapshottableMap map) {
  61.     this.snapshotVersion = version;
  62.     this.map = map;
  63.   }

  64.   public String get(String key) {
  65.     return map.get(key, snapshotVersion);
  66.   }
  67.   
  68.   public String toDebugString() {
  69.     return map.toDebugString(snapshotVersion);
  70.   }
  71. }

  72. // SnapshottableMap的实现
  73. class SnapshottableMap {
  74.   private int lastestVersion = 0;
  75.   private List<Snapshot> snapshots = new ArrayList<>();
  76.   private Map<String, ValueHistory> storage = new HashMap<>();
  77.   
  78.   public void put(String key, String value) {
  79.     ValueHistory history = storage.get(key);
  80.     if (history == null) {
  81.       history = new ValueHistory();
  82.       storage.put(key, history);
  83.     }
  84.     history.put(value, lastestVersion);
  85.   }
  86.   
  87.   public String get(String key) {
  88.     return get(key, lastestVersion);
  89.   }

  90.   // 微量级时间的create snapshot
  91.   public Snapshot createSnapshot() {
  92.     Snapshot snapshot = new Snapshot(lastestVersion++, this);
  93.     snapshots.add(snapshot);
  94.     return snapshot;
  95.   }

  96.   public List<Snapshot> getSnapshots() {
  97.     return snapshots;
  98.   }

  99.   public String get(String key, int version) {
  100.     ValueHistory history = storage.get(key);
  101.     if (history == null) {
  102.       return null;
  103.     }
  104.     return history.get(version);
  105.   }
  106.   
  107.   // 打印某一个version的所有值用于调试
  108.   public String toDebugString(int version) {
  109.     StringBuilder sb = new StringBuilder();
  110.     for (String key : storage.keySet()) {
  111.       final String value = get(key, version);
  112.       if (value != null) {
  113.         sb.append(key + ": " + value + "\n");
  114.       }
  115.     }
  116.     return sb.toString();
  117.   }
  118. }

  119. class ValueHistory {
  120.   // 代码逻辑保证slots中version号码一定是有序的
  121.   private ArrayList<ValueSlot> slots = new ArrayList<>();
  122.   
  123.   public void put(String value, int version) {
  124.     // 修改最后一个version或者是添加新version
  125.     if (!slots.isEmpty()) {
  126.       ValueSlot lastSlot = slots.get(slots.size() - 1);
  127.       if (lastSlot.getVersion() == version) {
  128.         lastSlot.SetValue(value);
  129.         return;
  130.       }
  131.     }
  132.     slots.add(new ValueSlot(version, value));
  133.   }
  134.   
  135.   public String get(int version) {
  136.     // 二分查找version
  137.     int index = Collections.binarySearch(slots, version);
  138.     if (index < 0) {
  139.       if (index == -1) {
  140.         return null;
  141.       }
  142.       // 不存在指定version,但是有之前的version
  143.       index = -index - 2;
  144.     }
  145.     return slots.get(index).getValue();
  146.   }
  147. }

  148. class ValueSlot implements Comparable<Integer> {
  149.   private int version;
  150.   private String value;  
  151.   public ValueSlot(int version, String value) {
  152.     this.version = version;
  153.     this.value = value;
  154.   }
  155.   public int getVersion() {
  156.     return version;
  157.   }
  158.   public void SetValue(String newValue) {
  159.     value = newValue;
  160.   }
  161.   public String getValue() {
  162.     return value;
  163.   }  
  164.   @Override
  165.   public int compareTo(Integer other) {
  166.     return version - other;
  167.   }
  168. }
复制代码

评分

参与人数 2大米 +80 收起 理由
admin + 40
14417335 + 40 很有用的信息!

查看全部评分

回复

使用道具 举报

🔗
liaohs49 2019-3-12 00:48:21 | 只看该作者
全局:
用的list,然后binary search搜索。
优化了空间。

  1. import java.util.ArrayList;
  2. import java.util.HashMap;
  3. import java.util.List;

  4. public class SnapHashMap<K, V> {
  5.         class VersionedValue {
  6.                 public V val;
  7.                 public int ver;
  8.                
  9.                 public VersionedValue(int ver, V val) {
  10.                         this.ver = ver;
  11.                         this.val = val;
  12.                 }
  13.         }

  14.         private HashMap<K, ArrayList<VersionedValue>> map;
  15.         private int version = 0;

  16.         public SnapHashMap() {
  17.                 map = new HashMap<K, ArrayList<VersionedValue>>();
  18.         }

  19.         public int snap() {
  20.                 return this.version++;
  21.         }
  22.        
  23.         public V getVerVal(K key, int ver) {
  24.                 if (ver >= this.version) {
  25.                         return null;
  26.                 }
  27.                 ArrayList<VersionedValue> verVals = map.get(key);
  28.                 if (verVals.get(0).ver > ver) {
  29.                         return null;
  30.                 }
  31.                 if (verVals.get(verVals.size() - 1).ver < ver) {
  32.                         return verVals.get(verVals.size() - 1).val;
  33.                 }
  34.                 // binary search ver
  35.                 return binarySearch(verVals, ver);
  36.         }
  37.        
  38.         // find equal or biggest ver smaller than target version
  39.         public V binarySearch(List<VersionedValue> list, int targetVer) {
  40.                 int left = 0, right = list.size() - 1;
  41.                 while (left + 1 < right) {
  42.                         int mid = left + (right - left) / 2;
  43.                         if (list.get(mid).ver > targetVer) {
  44.                                 right = mid;
  45.                         } else if (list.get(mid).ver < targetVer) {
  46.                                 left = mid;
  47.                         } else {
  48.                                 return list.get(mid).val;
  49.                         }
  50.                 }
  51.                 return list.get(left).val;
  52.         }

  53.         public void put(K key, V value) {
  54.                 if (!map.containsKey(key)) {
  55.                         VersionedValue verVal = new VersionedValue(this.version, value);
  56.                         ArrayList<VersionedValue> initVerVals = new ArrayList<VersionedValue>();
  57.                         initVerVals.add(verVal);
  58.                         map.put(key, initVerVals);
  59.                 } else {
  60.                         ArrayList<VersionedValue> verVals = map.get(key);
  61.                         // check if is new version
  62.                         if (verVals.get(verVals.size() - 1).ver == this.version) { // if ver exist
  63.                                 verVals.get(verVals.size() - 1).val = value;
  64.                         } else { // if ver not exist, then add
  65.                                 verVals.add(new VersionedValue(this.version, value));
  66.                         }
  67.                 }
  68.         }
  69.        
  70.         public V get(K key) {
  71.                 ArrayList<VersionedValue> verVals = map.get(key);
  72.                 return verVals.get(verVals.size() - 1).val;
  73.         }

  74.         public static void main(String[] args) {
  75.                 SnapHashMap<Integer, Integer> map = new SnapHashMap<>();
  76.                 map.put(1, 11);
  77.                 System.out.println("ver " + map.snap());
  78.                 map.put(1, 12);
  79.                 map.put(2, 23);
  80.                 System.out.println("ver " + map.snap());
  81.                 map.put(1, 14);
  82.                 System.out.println("val " + map.get(1));
  83.                 System.out.println("ver val " + map.getVerVal(2, 0));
  84.                 System.out.println("ver val " + map.getVerVal(2, 1));
  85.         }
  86. }
复制代码

评分

参与人数 2大米 +80 收起 理由
admin + 40
14417335 + 40 很有用的信息!

查看全部评分

回复

使用道具 举报

🔗
BridgeHUHX 2019-3-14 04:05:45 | 只看该作者

google snapshot

全局:
implement 4 interfaces for class Snapshot, 面之前没见过,后来好像看到是高频题,不知道怎么才是最佳。如果用数组,每次snapshot增加时复制,实现容易,get O(1), set O(n),空间复杂度不好。估计不是面试官想要的。

您好!
本帖隐藏的内容需要积分高于 100 才可浏览
您当前积分为 0。
使用VIP即刻解锁阅读权限或查看其他获取积分的方式
游客,您好!
本帖隐藏的内容需要积分高于 100 才可浏览
您当前积分为 0。
VIP即刻解锁阅读权限 或 查看其他获取积分的方式
Unlock interview details and practice with AI
Curated Interview Questions from Top Companies




评分

参与人数 2大米 +6 收起 理由
admin + 3
14417335 + 3 给你点个赞!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表