隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0

          導航

          <2013年11月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          公告

          關注我的新浪微博

          我的著作









          常用鏈接

          留言簿(126)

          我參與的團隊

          隨筆分類(818)

          隨筆檔案(310)

          文章分類(1)

          文章檔案(8)

          相冊

          ADSL、3G查詢

          CSDN

          eclipse

          ibm

          Java EE

          Linux

          Web

          云服務

          代理網站

          關注的網站

          協議

          喜歡的Blog

          國內廣告平臺

          圖書出版

          在線培訓

          開發工具

          微博客戶端

          手機鈴聲

          操作系統

          • ReactOS
          • 一個與windowXP/2003兼容的操作系統

          數學

          文件格式

          源碼資源

          移動(Mobile)

          編程語言

          英語學習

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 1972272
          • 排名 - 6

          最新評論

          閱讀排行榜

          評論排行榜

          Twitter算法面試題詳解(Java實現)

          最近在網上看到一道Twitter的算法面試題,網上已經有人給出了答案,不過可能有些人沒太看明白(我也未驗證是否正確),現在給出一個比較好理解的答案。先看一下題目。

          圖1

               先看看圖圖1。可以將方塊看做磚。題干很簡單,問最多能放多少水。例如,圖2就是圖1可放的最多水(藍色部分),如果將一塊磚看做1的話,圖2就是能放10個單位的水。

          圖2

          再看個例子

          圖3

          圖3可以放17個單位的水。

          上面每一個圖的磚墻用int數組表示,每一個數組元素表示每一列磚墻的磚數(高度),例如,圖3用數組表示就是int[] wallHeights = new int[]{2, 5, 1, 3, 1, 2, 1, 7, 7, 6};

          這里某人給出了python的算法點擊打開鏈接,不過有人說有問題,有python環境的可以驗證。現在給出我的Java算法。

          算法原理

                其實很簡單,我的算法并不是累加的,而是用的減法,先用圖3為例。只需要找到所有墻中最高的,然后再找出第二高的。如果兩堵墻緊鄰者,就忽略它,否則算一 下 如果墻之間沒有任何其他的磚的情況下可以有多少水(只是一個乘法而已),然后掃描兩堵墻之間有多少塊磚,減去這個磚數就可以了。最后用遞歸處理。將兩堵墻 兩側到各自的左右邊界再重新進行前面的操作(遞歸處理)。直到無墻可處理。 用遞歸方法很容易理解。下面看一下算法的詳細代碼。

          復制代碼
          public class Test  
          {  
              static int result = 0;  //  最終結果  
              static int[] wallHeights = new int[]  
              {1,6,1,2,3,4,100,1,9};  //  表示所有的墻的高度  
            
              public static void process(int start, int end)  
              {  
                  //  first:start和end之間最高的墻  
                  //  second:start和end之間第二高的墻  
                  int first = 0, second = 0;  
                  //  firstIndex:第一高的墻在wallHeights中的索引  
                  //  secondIndex:第二高的墻在wallHeights中的索引  
                  int firstIndex = 0, secondIndex = 0;  
                  //  兩堵墻必須至少有一堵墻的距離  
                  if (end - start <= 1)  
                      return;  
                  //  開始獲取第一高和第二高墻的磚數  
                  for (int i = start; i <= end; i++)  
                  {  
                      if (wallHeights[i] > first)  
                      {  
                          second = first;  
                          secondIndex = firstIndex;  
                          first = wallHeights[i];  
                          firstIndex = i;  
                      }  
                      else if (wallHeights[i] > second)  
                      {  
                          second = wallHeights[i];  
                          secondIndex = i;  
                      }  
                  }  
            
                  //  獲取左側墻的索引  
                  int startIndex = Math.min(firstIndex, secondIndex);  
                  //  獲取右側墻的索引  
                  int endIndex = Math.max(firstIndex, secondIndex);  
                  //  計算距離  
                  int distance = endIndex - startIndex;  
                  //  如果第一高的墻和第二高的墻之間至少有一堵墻,那么開始計算這兩堵墻之間可以放多少個單位的水  
                  if (distance > 1)  
                  {  
                      result = result + (distance - 1) * second;  
                      //  減去這兩堵墻之間的磚數  
                      for (int i = startIndex + 1; i < endIndex; i++)  
                      {  
                          result -= wallHeights[i];  
                      }  
                        
                  }  
                  //  開始遞歸處理左側墻距離開始位置能放多少水  
                  process(start, startIndex);  
                  //  開始遞歸處理右側墻距離結束位置能放多少水  
                  process(endIndex, end);  
              }  
              public static void main(String[] args)  
              {  
                  process(0, wallHeights.length - 1);  
                  System.out.println(result); 
              }  
          }  
          復制代碼

          代碼中的測試用例的結果是22。下面是幾組測試用例。

           

          [2,5,1,2,3,4,7,7,6]   結果:10
          [2,5,1,3,1,2,1,7,7,6]  結果:17
          [6,1,4,6,7,5,1,6,4]   結果:13
          [9,6,1,2,3,4,50,1,9]  結果:37


          有其他算法的(語言不限)歡迎跟帖

           





          Android開發完全講義(第2版)(本書版權已輸出到臺灣)

          http://product.dangdang.com/product.aspx?product_id=22741502



          Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


          新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

          posted on 2013-11-03 18:03 銀河使者 閱讀(8617) 評論(4)  編輯  收藏 所屬分類: algorithm 原創

          評論

          # re: Twitter算法面試題詳解(Java實現)  回復  更多評論   

          囧,遞歸lol~ 貼一個自己在leetcode上的實現。因為是直接在oj上寫的,不考慮額外空間問題,當然了這段代碼可以重構^_^.

          http://oj.leetcode.com/problems/trapping-rain-water/

          class Solution {
          public:
          int trap(int A[], int n) {
          // Note: The Solution object is instantiated only once and is reused by each test case.

          // easiest and intuitive way:
          // caculate the (left_max, right_max) for each element A[i]
          // example:
          // for the given array A = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1], the points whould be:
          // B = [(0, 3), (1, 3), (1, 3), (2, 3), (2, 3), (2, 3), (2, 3), (3, 2), (3, 2), (3, 2), (3, 1)]
          // then let SUM = sum( min(Bi) ) for i = 0 to n-1
          // return SUM - sum(Ai) for i = 0 to n-1
          // and hope this works!
          // luckily, it works!

          vector<int> left(n, 0), right(n, 0);
          int max = 0;
          for(int i=0; i<n; i++)
          {
          if(A[i] > max)
          max = A[i];

          left[i] = max; // don't use push_back
          }

          // for right
          max = 0;
          for(int i=n-1; i>=0; i--)
          {
          if(A[i] > max)
          max = A[i];

          right[i] = max;
          }

          int sum=0;
          for(int i=0; i<n; i++)
          {
          int min = (left[i] < right[i]) ? left[i] : right[i];
          sum += (min-A[i]); // don't forget to subtract A[i]
          }

          return sum;
          }
          };
          2013-11-19 01:57 | zyzz

          # re: Twitter算法面試題詳解(Java實現)  回復  更多評論   

          好東西 學習了
          2013-12-05 10:23 | 左岸

          # re: Twitter算法面試題詳解(Java實現)[未登錄]  回復  更多評論   

          package yang.twitter;

          /**
          * @author dy35978
          *
          */
          public class TwitterProcess {
          private static int [] wallHeights = {1,6,1,2,3,4,100,1,9};
          private static int result = 0;//最多裝水
          private static void process(int start, int end){
          int firstWall = 0;//最高墻
          int secondWall = 0;//次高墻
          int firstIndex = 0;//最高墻下標
          int secondIndex = 0;//次高墻下標
          int maxIndex = 0;//較大下標
          int minIndex = 0;//較小下標
          //end-start<=1 不只是等于1,注意
          if(end-start<=1){
          return;
          }
          for(int i=0;i<end+1;i++){
          if(wallHeights[i]>=firstWall){
          secondWall = firstWall;
          secondIndex = firstIndex;
          firstWall = wallHeights[i];
          firstIndex = i;
          }else{
          if(wallHeights[i]>=secondWall){
          secondIndex = i;
          secondWall = wallHeights[i];
          }
          }
          }
          maxIndex = secondIndex>firstIndex?secondIndex:firstIndex;// Math.min(firstIndex, secondIndex);
          minIndex = secondIndex<firstIndex?secondIndex:firstIndex;// Math.max(firstIndex, secondIndex);
          if(maxIndex-minIndex>1){
          result =result+ secondWall*(maxIndex-minIndex-1);
          for(int i=minIndex+1;i<maxIndex;i++){
          result = result-wallHeights[i];
          }
          }
          // 開始遞歸處理左側墻距離開始位置能放多少水
          process(start,minIndex);
          // 開始遞歸處理右側墻距離結束位置能放多少水
          process(maxIndex,end);
          }

          /**
          * @param args
          */
          public static void main(String[] args) {
          // TODO Auto-generated method stub

          process(0,wallHeights.length-1);
          System.out.println("wallHeights結果:"+result);
          }

          }
          2013-12-17 11:32 | Blues

          # re: Twitter算法面試題詳解(Java實現)  回復  更多評論   

          很難啊.
          2014-07-24 13:21 | 微觀互聯網
          主站蜘蛛池模板: 延川县| 浮梁县| 竹溪县| 乐清市| 东乌珠穆沁旗| 凌海市| 屏东市| 安庆市| 安康市| 宁安市| 张家界市| 棋牌| 宜兴市| 阳西县| 遂宁市| 宜君县| 绿春县| 黄陵县| 贡觉县| 屯昌县| 宜阳县| 石台县| 泰兴市| 伊春市| 南和县| 大同县| 内丘县| 余庆县| 章丘市| 乌拉特后旗| 迁西县| 宜宾市| 永城市| 安平县| 聂荣县| 沧州市| 八宿县| 凤城市| 肥城市| 九龙坡区| 永济市|