IT技術小屋

          秋風秋雨,皆入我心

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            38 隨筆 :: 1 文章 :: 19 評論 :: 0 Trackbacks

          #

          Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.
          OJ's undirected graph serialization:
          Nodes are labeled uniquely.
          We use # as a separator for each node, and , as a separator for node label and each neighbor of the node.
          As an example, consider the serialized graph {0,1,2#1,2#2,2}.
          The graph has a total of three nodes, and therefore contains three parts as separated by #.
          1. First node is labeled as 0. Connect node 0 to both nodes 1 and 2.
          2. Second node is labeled as 1. Connect node 1 to node 2.
          3. Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.

          Visually, the graph looks like the following:
                 1
                / \
               /   \
              0 --- 2
                   / \
                   \_/

          需要對原圖進行BFS搜索,其中Set<UndirectedGraphNode> visited對已經訪問過的節點進行記錄,Map<UndirectedGraphNode, UndirectedGraphNode> map用來記錄新老節點的對應關系。代碼實現如下:
           1 import java.util.HashMap;
           2 import java.util.HashSet;
           3 import java.util.LinkedList;
           4 import java.util.Map;
           5 import java.util.Queue;
           6 import java.util.Set;
           7 
           8 public class CloneGraph {
           9     public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
          10         if (node == null)
          11             return node;
          12         Queue<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>();
          13         queue.add(node);
          14         Set<UndirectedGraphNode> visited = new HashSet<UndirectedGraphNode>();
          15         Map<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap<UndirectedGraphNode, UndirectedGraphNode>();
          16         while (!queue.isEmpty()) {
          17             UndirectedGraphNode n = queue.remove();
          18             if (visited.contains(n))
          19                 continue;
          20             visited.add(n);
          21             UndirectedGraphNode clone;
          22             if (!map.containsKey(n)) {
          23                 clone = new UndirectedGraphNode(n.label);
          24                 map.put(n, clone);
          25             } else {
          26                 clone = map.get(n);
          27             }
          28             for (UndirectedGraphNode child : n.neighbors) {
          29                 queue.add(child);
          30                 UndirectedGraphNode cloneChild;
          31                 if (!map.containsKey(child)) {
          32                     cloneChild = new UndirectedGraphNode(child.label);
          33                     map.put(child, cloneChild);
          34                 } else {
          35                     cloneChild = map.get(child);
          36                 }
          37                 clone.neighbors.add(cloneChild);
          38             }
          39         }
          40         return map.get(node);
          41     }
          42 }
          posted @ 2013-12-19 10:36 Meng Lee 閱讀(979) | 評論 (0)編輯 收藏

          There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. 

          You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.

          Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.

          Note: The solution is guaranteed to be unique.

          首先,這個題目要明確如果gas[0] + gas[1] + ... + gas[n] >= cost[0] + cost[1] + .. + cost[n],那么這個題目一定有解。因為,根據條件移項可得:
          (gas[0] - cost[0]) + (gas[1] - cost[1]) + ... + (gas[n] - cost[n]) >= 0,由于最終結果大于等于零,因此一定可以通過加法交換律,得到一個序列,使得中間結果都為非負。因此可以將算法實現如下:
           1 public class GasStation {
           2     public int canCompleteCircuit(int[] gas, int[] cost) {
           3         int sum = 0, total = 0, len = gas.length, index = -1;
           4         for (int i = 0; i < len; i++) {
           5             sum += gas[i] - cost[i];
           6             total += gas[i] - cost[i];
           7             if (sum < 0) {
           8                 index = i;
           9                 sum = 0;
          10             }
          11         }
          12         return total >= 0 ? index + 1 : -1;
          13     }
          14 }
          posted @ 2013-12-19 09:29 Meng Lee 閱讀(393) | 評論 (1)編輯 收藏

          Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:
              1. Only one letter can be changed at a time
              2. Each intermediate word must exist in the dictionary
          For example,
          Given:
              start = "hit"
              end = "cog"
              dict = ["hot","dot","dog","lot","log"]
              As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
              return its length 5.
          Note:
              1. Return 0 if there is no such transformation sequence.
              2. All words have the same length.
              3. All words contain only lowercase alphabetic characters.

          第一個思路是遍歷dict中的每一個元素,看是不是和當前word只相差一個字符,如果是則作為新的當前word,直到當前word與target只相差一個字符。實現代碼如下:
           1 public class Solution {
           2     public int ladderLength(String start, String end, HashSet<String> dict) {
           3         HashSet<String> trash = new HashSet<String>();
           4         return searchWordLadder(start, end, dict, trash) + 1;
           5     }
           6 
           7     private int searchWordLadder(String start, String end, HashSet<String> dict, HashSet<String> trash) {
           8         if (stringDiff(start, end) == 1) return 1;
           9         if (dict.size() == trash.size()) return 0;
          10         int steps = Integer.MAX_VALUE;
          11         for (String word : dict) {
          12             if (!trash.contains(word) && stringDiff(start, word) == 1) {
          13                 trash.add(word);
          14                 int lt = searchWordLadder(word, end, dict, trash);
          15                 if (lt != 0 && lt < steps) {
          16                     steps = lt;
          17                 }
          18                 trash.remove(word);
          19             }
          20         }
          21         return steps == Integer.MAX_VALUE ? 0 : steps + 1;
          22     }
          23     
          24     private int stringDiff(String s1, String s2) {
          25         int diff = 0;
          26         int length = s1.length();
          27         for (int i = 0; i < length; i++) {
          28             if (s1.charAt(i) != s2.charAt(i)) {
          29                 diff++;
          30             }
          31         }
          32         return diff;
          33     }
          34 }
          這個算法可以通過小數據測試,但是在大數據下報超時錯誤。主要問題是算法復雜度較高,由于dict中的單詞是亂序的,因此最壞情況下需要遍歷所有可能的轉換路徑才能做出判斷。
          改變思路,其實可以通過trie樹的BFS搜索獲得結果,由于BFS是分層遍歷的,因此找到一個解之后就可以馬上返回,復雜度是O(N),N是原單詞的長度。實現代碼如下:
           1 public class WordLadder {
           2     public int ladderLength(String start, String end, HashSet<String> dict) {
           3         if (dict.size() == 0)
           4             return 0;
           5         int currentLevel = 1;
           6         int nextLevel = 0;
           7         int step = 1;
           8         boolean found = false;
           9         Queue<String> st = new LinkedList<String>();
          10         HashSet<String> visited = new HashSet<String>();
          11         st.add(start);
          12         while (!st.isEmpty()) {
          13             String s = st.remove();
          14             currentLevel--;
          15             if (stringDiff(s, end) == 1) {
          16                 found = true;
          17                 step++;
          18                 break;
          19             } else {
          20                 int length = s.length();
          21                 StringBuffer sb = new StringBuffer(s);
          22                 for (int i = 0; i < length; i++) {
          23                     for (int j = 0; j < 26; j++) {
          24                         char c = sb.charAt(i);
          25                         sb.setCharAt(i, (char) ('a' + j));
          26                         if (dict.contains(sb.toString())
          27                                 && !visited.contains(sb.toString())) {
          28                             nextLevel++;
          29                             st.add(sb.toString());
          30                             visited.add(sb.toString());
          31                         }
          32                         sb.setCharAt(i, c);
          33                     }
          34                 }
          35             }
          36             if (currentLevel == 0) {
          37                 currentLevel = nextLevel;
          38                 nextLevel = 0;
          39                 step++;
          40             }
          41         }
          42         return found ? step : 0;
          43     }
          44 
          45     private int stringDiff(String s1, String s2) {
          46         int diff = 0;
          47         int length = s1.length();
          48         for (int i = 0; i < length; i++) {
          49             if (s1.charAt(i) != s2.charAt(i)) {
          50                 diff++;
          51             }
          52         }
          53         return diff;
          54     }
          55 }
          其中利用了隊列對trie樹進行BFS。
          posted @ 2013-12-19 09:11 Meng Lee 閱讀(1531) | 評論 (0)編輯 收藏

          VS 2010中添加C++目錄的功能已經被否決,可以通過添加User Property Sheet的方法來添加。

          例如,添加Microsoft.Cpp.Win32.user.props:
          <?xml version="1.0" encoding="utf-8"?>
          <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
            
          <PropertyGroup>
              
          <ExecutablePath>$(VCInstallDir)PlatformSDK\bin;$(VSInstallDir)\SDK\v2.0\bin;$(ExecutablePath)</ExecutablePath>
              
          <IncludePath>$(VCInstallDir)PlatformSDK\include;D:\Work\SQLite\SourceCode\sqlite-amalgamation-3_6_19;Z:\Common;C:\jdk1.6.0_02\include;$(IncludePath)</IncludePath>
              
          <ReferencePath>$(ReferencePath)</ReferencePath>
              
          <LibraryPath>$(VCInstallDir)PlatformSDK\lib;Z:\Lib;$(LibraryPath)</LibraryPath>
              
          <SourcePath>$(SourcePath)</SourcePath>
              
          <ExcludePath>$(VCInstallDir)PlatformSDK\include;$(ExcludePath)</ExcludePath>
            
          </PropertyGroup>
          </Project>

          屬性文件存放的位置是:
          %USERPROFILE%\Local Settings\Application Data\Microsoft\MSBuild\v4.0

          那么,這個屬性文件會應用到Win32平臺下所有的CPP項目中去。 
          posted @ 2011-08-15 10:55 Meng Lee 閱讀(2609) | 評論 (2)編輯 收藏

               摘要: 學習Ruby on Rails已經一段時間了,一直使用自帶的WEBrick服務器進行開發。WEBrick是一款純Ruby編寫的服務器,使用方便,很適合開發環境下進行系統調試。但是它不支持多線程訪問,換句話說,所有的Ruby請求都是按照到達的時間先后,順序處理的,因此效率不高,無法應用在實際的生產環境中。所以今天研究了一下如何將Rails3應用部署到真實的線上環境中。  閱讀全文
          posted @ 2011-08-02 10:25 Meng Lee 閱讀(1698) | 評論 (0)編輯 收藏

               摘要: 最近決定開始閱讀Linux 0.11的源代碼。學習Linux操作系統的核心概念最好的方法莫過于閱讀源代碼。而Linux當前最新的源代碼包已經有70MB左右,代碼十分龐大,要想深入閱讀十分困難。而Linux早期的0.11版本雖然有諸多局限,但是具備了現代操作系統的完備功能,一些基本概念沿用到了當前版本,并且代碼只有300KB,非常適合閱讀。  閱讀全文
          posted @ 2011-08-02 10:05 Meng Lee 閱讀(3158) | 評論 (1)編輯 收藏

          周末用了下新浪微博開放平臺API和官方發布的Java客戶端,感覺可以用兩個字形容:坑爹!

          先說說遇到的幾個極其弱智的bug吧:

          1)分頁

          官方API文檔里面對數據分頁獲取的說明是使用cursor和count這兩個參數。其中,cursor指明了起始記錄的位置,而count指明了當前每頁的記錄條數,請求第一頁的時候cursor為-1。返回結果會給出next_cursor,指明下一頁的起始位置。

          這個設計看起來不錯,問題是根據這個文檔,得到的結果會有重復。也就是說同一條記錄會出現在多個頁面中,而且這種重復出現的頻率是隨機的。試想連程序的行為都無法預測,叫別人怎么開發應用?!

          更搞笑的是,官方發布的Java客戶端居然把cursor寫成了page,導致了不管怎么設置參數,返回的都是很多重復的數據,但重復的比例又是隨機的!難道新浪沒有對這個客戶端進行過簡單的測試就發布了嗎?無法想象!!

          2)返回結果的解析

          好不容易把用戶信息得到了,新浪自己寫了一個JavaBean用來表示一個User的信息。問題是把JSON解析成Java對象的時候,居然把布爾屬性字段解析錯了,導致每次返回都是false,好不容易得到的數據就這么泡湯了~~難道解析JSON很難嘛??敢測試下再發布嗎?

          3)詭異的負數

          我小學學到的知識告訴我,人的個數不可能是負數。于是我天真的在followers_count這個數據庫字段上加了unsigned,本以為教數據庫的老師應該很開心吧,這孩子設計的數據庫還蠻嚴謹的,而且應該能夠和新浪的數據很好地匹配。

          于是我開心的運行程序,詭異的錯誤出現了:超出字段范圍。暈,于是檢查所有數字字段是否超過了表示范圍,N遍檢查過后確認數據庫沒問題,糾結~~于是看log,發現返回的數據里面,有一個項的followers_cout字段是-2,負數!!!尼瑪這人雖然粉絲少了點,也不至于欠你新浪兩個粉絲吧,我當時就凌亂了,于是加了很多異常數據的判斷和檢查。。。

          4)詭異的版權信息

          Java客戶端里面很多文件的作者信息是:@author Yusuke Yamamoto - yusuke at mac.com,感覺這應該是一個蘋果公司的員工開發的,然后新浪拿過來,沒有code review,沒有測試,就直接官方發布了。。。

          這樣不重視代碼質量,把產品構建在志愿者的貢獻之上,我覺得是新浪的恥辱,更是中國互聯網產業的頑癥惡疾。

          以上只是我這兩天試用了一小部分API的感受。由于各種bug,我不得不閱讀源代碼,并根據我的需求改寫代碼,甚至一度我準備拋棄這個客戶端,直接用HTTP調用。反正最后嚴重降低了我的效率。

          回想起這兩天傳高鐵出事是程序員的問題,我看要按照新浪這質量標準,不知道還要出什么大事~~

           

          posted @ 2011-07-31 20:49 Meng Lee 閱讀(3818) | 評論 (11)編輯 收藏

               摘要: Axis2/C是一個用C語言實現的Web Service引擎。 Axis2/C基于Axis2架構,支持SOAP1.1和SOAP1.2協議,并且支持RESTful風格的Web Service。基于Axis2/C的Web Service可以同時暴露為SOAP和RESTful風格的服務。 最近研究了一下Axis2/C,這篇文章詳述了如何利用Axis2/C發布一個Web Service,并通過...  閱讀全文
          posted @ 2011-07-05 16:33 Meng Lee 閱讀(3845) | 評論 (1)編輯 收藏

          Memcached是被廣泛使用的分布式緩存技術。不同的語言有不同的Memcached客戶端程序,對于Java客戶端來說,首推Memcached Java Client(http://github.com/gwhalin/Memcached-Java-Client )。

          這次,Memcached Java Client推出的2.6.1發布版是基于全新的performance分支,具有如下重大改進:

          1. 較之老版本,在性能上有300%左右的提升;
          2. 兼容老版本,用戶無須修改自己的源代碼;
          3. 支持多個memcached協議,包括text,udp和binary協議;
          4. 支持SASL認證機制;
          5. 重新實現的連接池,修復了之前的連接數太多所導致的OutOfMemory異常;
          6. 加入了slf4j logger支持,使得開發人員可以方便的記錄日志;
          7. 支持自定義的對象序列化方法。

          這個分支由Schooner Information Technology貢獻,并由Schooner中國團隊完成開發,可以通過以下郵箱聯系作者:jowett.lee@gmail.com

          可以從這里下載二進制包:https://github.com/gwhalin/Memcached-Java-Client/downloads 
          源代碼在github上,http://github.com/gwhalin/Memcached-Java-Client ,然后選擇performance分支。

          下面是一些性能測試的數據,包括了當前流行的Memcached Java Client。其中,schooner指的是這個分支的text protocol, schooner_bin指的是binary protocol,鏈接是:https://github.com/gwhalin/Memcached-Java-Client/wiki/PERFORMANC

          轉載請注明出處:http://www.aygfsteel.com/menglee/archive/2011/06/29/353375.html


          posted @ 2011-06-29 18:09 Meng Lee 閱讀(2460) | 評論 (2)編輯 收藏

          僅列出標題
          共4頁: 上一頁 1 2 3 4 
          主站蜘蛛池模板: 壶关县| 中方县| 吉林省| 墨竹工卡县| 广宗县| 金秀| 和平县| 张家川| 北票市| 长岛县| 青铜峡市| 分宜县| 芦溪县| 松滋市| 金寨县| 林口县| 孝义市| 皋兰县| 江陵县| 漳州市| 如东县| 新疆| 涿鹿县| 西和县| 吴江市| 乌鲁木齐县| 高清| 景洪市| 濉溪县| 南木林县| 金溪县| 吉隆县| 高阳县| 邛崃市| 温宿县| 广平县| 农安县| 拜泉县| 肇源县| 苏州市| 汪清县|