2017年4月19日 星期三

[Leetcode C++解析] 447. Number of Boomerangs

大家好
這次要講的題目是Number of Boomerangs
題目網址 https://leetcode.com/problems/number-of-boomerangs/#/description

這一題小弟覺得不算是簡單的題目
(可能我數學不夠好XDD)
在此稍微說明一下題目:
給你一個包含n個tuple
(tuple的中文好像是數對,就是每一個tuple包含兩個數字x,y)
要在這n個tuple之中
找出符合像"boomerang"條件的組數量
也就是說從中抓任意三個點A.B.C
從A到B的距離"等於"從A到C的距離
其中(A,B,C)和(A,C,B)是不一樣的組合(考慮順序)

最多500個tuple
數值範圍介於-10000~10000

舉例來說
輸入:[[0,0],[1,0],[2,0],[0,1]]
符合boomerang的條件有
[1,0],[0,0],[2,0]
[2,0],[0,0],[1,0]
[0,0],[1,0],[0,1]
[0,0],[0,1],[1,0]
總共4種
因此輸出4

《以下是我的解題方式》
一開始我想了很久不知從何下手
用手算還算容易
後來一直盯著上面的結果看
就大致想到了
先任意抓出兩個點算長度
固定前面的點讓他去跟剩下的點算長度後做比較
有找到一樣的就把結果存起來

不過這樣有個問題是
時間複雜度會到O(n^3)
(最外面的一層是控制第一個點,中間那層控制第二個點,最裡面那層控制第三個點)
在別的相似題中會出現TLE的狀態

後來求助大神後
改成以下的作法

一樣先計算其中兩個點的長度
藉由unordered_map的container來做table
key:兩點的長度(平方)
value:有幾組tuple是這個長度

每算完一次兩點長度
就把這長度對應的那一欄+1
算完之後
由排列組合的概念:
對於每固定一個點之後
在剩下的點中距離這個點為___的個數是n
則表示能構成boomerange的種類有
P(n,2) =  n! / (n-2)! = n * (n-1)
再把答案加總即可

舉一個較簡單的例子
輸入:[[0,0],[1,0],[2,0],[0,1]]

以上面的例子來說
所有的可能性為
[0,0],[1,0] → 1
[0,0],[0,1] → 1
[0,0],[2,0] → 4
2! / 0! = 2

[1,0],[0,0] → 1
[1,0],[2,0] → 1
[1,0],[0,1] → 2
2! / 0! = 2

[2,0],[0,0] → 4
[2,0],[1,0] → 1
[2,0],[0,1] → 5
No~

[0,1],[0,0] → 1
[0,1],[1,0] → 2
[0,1],[2,0] → 5
No~

答案為2+2=4
《曾經錯過的測資》


《程式碼在這》
【小提醒:盡量自己先參考上面的想法寫出來,這樣比較不會有背程式碼的概念】


class Solution {
public:
    int numberOfBoomerangs(vector<pair<int, int>>& points) {
        int ans=0;
     
        for(int i=0;i<points.size();++i){
            unordered_map<long,int> res;
            for(int j=0;j<points.size();++j){
                if(i==j) continue;//
             
                int x = points[i].first - points[j].first;
                int y = points[i].second - points[j].second;
                long distance = x*x + y*y;
             
                ++res[distance];
            }
         
            for(auto& ptr : res){
                if(ptr.second>1){
                    ans += (ptr.second * (ptr.second -1));
                }
            }
         
        }
     
        return ans;
    }
};

2017年4月17日 星期一

[Leetcode C++解析] 268. Missing Number

大家好
這次要講的題目是Missing Number
題目網址 https://leetcode.com/problems/missing-number/#/description

這一題大致上算是簡單的題目
在此稍微說明一下:
給你一個包含n個不會重複字的陣列
其值介於0到n
希望你從中找出陣列之中唯一缺少的一個數字
並且輸出該數字

舉例來說
陣列#1 : [0 1 2 4]
答案為3
陣列#2 : [0 1 2]
答案為3

相信有些人可能不理解陣列#2的答案為何是3
(明明數字都有了幹嘛還要多一個3)

由於題目是說給n個不重複的數字
且這些數字的值介於0到n之間
以#2的例子來說
陣列共有3個數字0.1.2
因此n=3

《以下是我的解題方式》
因為數字不重複
所以可以透過累加的方式將陣列的n個數總和起來
再用該有的數總和減掉上面的總和就是答案囉

以#1來說
陣列的總和=0+1+2+4=7
應有的總和=0+1+2+3+4=10
所求=10-7=3

《曾經錯過的測資》
陣列 : []
陣列 : [0]

《程式碼在這》
【小提醒:盡量自己先參考上面的想法寫出來,這樣比較不會有背程式碼的概念】


class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int sum=0,sz=nums.size();
        for(int i = 0 ; i < sz ;++i ) sum += nums[i];
     
        return sz * ( sz + 1 ) / 2 - sum;
    }
};

[袁賢銘的OS作業]HW3筆記

架好三台VM
並且完成SSH及MPICH
參考HW2筆記

安裝OpenCV
http://docs.opencv.org/3.2.0/d7/d9f/tutorial_linux_install.html

git clone https://github.com/opencv/opencv.git
cd ~/opencv
mkdir build
cd build

使用CMake來bulid執行檔
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local ..

make -j2 用兩核心來平行編譯

安裝編譯好的library
sudo make install

驗證OpenCV有無安裝成功
進到source資料夾並由MPIC++編譯器執行編譯
cd source
make
再由mpi執行程式產生負片的圖片
mpirun -np 1 -host master -x LD_LIBRARY_PATH=/usr/local/lib/ ./test <圖片檔名>

[Leetcode C++解析] 350. Intersection of Two Arrays II

大家好
這次要講的題目是Intersection of Two Arrays II
題目網址 https://leetcode.com/problems/intersection-of-two-arrays-ii/#/description

這一題大致上算是簡單的題目
不過他的題目說明沒有很清楚
一開始誤解了他的意思
在此稍微說明一下:
給你兩個陣列
希望你可以找出兩陣列之中的交集
並且不要求輸出結果的順序

舉例來說
陣列#1 : [1 3 5 7 9]
陣列#2 : [7 3 5 2]
答案為 [3 5 7]或[3 7 5]或[5 3 7]或[5 7 3]或[7 5 3]或[7 3 5] (就是不要求答案的順序)

《以下是我的解題方式》

因為不要求答案順序
因此將兩個input陣列先進行排序
以上面的舉例來說...
陣列#1 : [1 3 5 7 9]
陣列#2 : [2 3 5 7]

這樣的話只要從頭開始兩兩比較一下
把相同的數值放入存答案的陣列
最後再輸出即可

《曾經錯過的測資》
陣列#1 : [1]
陣列#2 : []
→要注意有空陣列的時候要怎麼處理
《程式碼在這》
【小提醒:盡量自己先參考上面的想法寫出來,這樣比較不會有背程式碼的概念】


class Solution {
public:
    /**
     * @param nums1 an integer array
     * @param nums2 an integer array
     * @return an integer array
     */
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        // Write your code here
        sort(nums1.begin(),nums1.end());
        sort(nums2.begin(),nums2.end());
     
        vector<int> res;
        res.clear();
        for(int i=0,j=0;i<nums1.size() && j<nums2.size();){
            if(nums1[i] > nums2[j]) ++j;
            else if(nums1[i] < nums2[j]) ++i;
            else {
                res.push_back(nums1[i]);
                ++i;++j;
            }
        }
        return res;
    }
};

2017年4月11日 星期二

[袁賢銘的OS作業]HW2筆記

安裝NFS(要確保slave可以有權限讀取和寫入master共享資料夾)
https://www.phpini.com/linux/debian-ubuntu-install-nfs-server
改hosts使用名稱代替IP
exports用法
http://linux.vbird.org/linux_server/0330nfs.php#nfsclient_servermount
FSTAB
https://wiki.archlinux.org/index.php/Fstab_(%E6%AD%A3%E9%AB%94%E4%B8%AD%E6%96%87)
新增使用者mpiuser(每台都要)
http://note.drx.tw/2008/03/ubuntuadduser-part1.html
新增使用者為sudoer
http://www.arthurtoday.com/2010/03/sudoer.html
安裝MPICH
sudo apt-get install mpich
把mpi_hello編譯測試有無安裝成功
mpicc mpi_hello.c -o mpi_hello
把編譯好的執行檔放入相同的位置
在master是放在Desktop,其他兩台就也是放在Desktop
在master執行mpi_hello
 mpiexec -n <total cpu number> -host master,slave1,slave2 ./mpi_hello
-n total cpu number代表你想要用幾個node來平行運算
-host 接你要平行處理的電腦名稱
兩種小測試
Pi test
mpirun -x LD_PRELOAD=/usr/lib/openmpi/lib/libmpi.so.12.0.2 -np 3 -host master,slave1,slave2 octave --eval 'pkg load mpi; Pi()'

Monte Carlo Algo. test
執行之前要先去/usr/share/octave/package/mpi...的資料夾
更改mc_example.m的內容
把olswrapper這個函式搬到另外一個新檔案叫做olswrapper.m
否則無法編譯
mpirun -x LD_PRELOAD=/usr/lib/openmpi/lib/libmpi.so.12.0.2 -np 3 -host master,slave1,slave2 octave --eval 'pkg load mpi; mc_example()'