LeetCode 939.最小面積矩形

前言

最近公司比較閑,那么自己也找點(diǎn)事情做龙巨。這道題呢在我寫這篇文章的時候谷歌笼呆、百度上都沒有答案,于是乎自己就來解答一下旨别。

題目

最小面積矩形
鏈接可能點(diǎn)不進(jìn)去诗赌,所以我把完整的題目寫在了下面。

描述:給定在 xy 平面上的一組點(diǎn)秸弛,確定由這些點(diǎn)組成的矩形的最小面積铭若,其中矩形的邊平行于 x 軸和 y 軸。
如果沒有任何矩形递览,就返回0叼屠。

示例 1:
輸入:[[1,1],[1,3],[3,1],[3,3],[2,2]]
輸出:4
示例 2:
輸入:[[1,1],[1,3],[3,1],[3,3],[4,1],[4,3]]
輸出:2

提示:
1 <= points.length <= 500
0 <= points[i][0] <= 40000
0 <= points[i][1] <= 40000
所有的點(diǎn)都是不同的。

題意很容易理解绞铃,就是找到所有能構(gòu)成矩形的4個點(diǎn)镜雨,然后求出它們的最小面積。示例1儿捧,最小面積為4由[[1,1],[1,3],[3,1],[3,3]]4個點(diǎn)構(gòu)成荚坞;示例2挑宠,面積為2由[[3,1],[3,3],[4,1],[4,3]]4個點(diǎn)構(gòu)成。

分析

看了題就知道這個題的難點(diǎn)在哪里:如何找到能構(gòu)成矩形的4個點(diǎn)颓影。于是乎我經(jīng)歷了下面的解題過程各淀。

Time Limit Exceeded

首先能直接想到的就是窮舉了,代碼也是出奇的簡單诡挂。

  int minAreaRect(vector<vector<int>>& points) {
        int minAreaValue = INT_MAX;
        //暴力窮舉
        for (int i = 0; i < points.size() - 3; i ++) {
            for (int j = i + 1; j < points.size() - 2; j ++) {
                for (int k = j + 1; k < points.size() - 1; k ++) {
                    for (int l = k + 1; l < points.size(); l ++) {
                        int value = areaRect(points[i],points[j],
                                             points[k],points[l]);
                        if(value == -1) {
                            continue;
                        }
                        minAreaValue = min(minAreaValue,value);
                    }
                }
            }
        }
        return minAreaValue == INT_MAX ? 0 : minAreaValue;
    }
    //這4個點(diǎn)能不能構(gòu)成矩形
    int areaRect(vector<int> one,vector<int> two,
                 vector<int> three,vector<int> four) {
        ///我就不貼代碼了碎浇,說一下思路:
        ///1:統(tǒng)計4個點(diǎn)的x、y是否分別是兩個值咆畏,并且分別都出現(xiàn)了2次南捂;
        ///2:得出面積。
    }

這個題的難度是中等旧找,所以不可能讓暴力求解AC的溺健。
暴力求解無法AC

Accept

于是乎我們轉(zhuǎn)變一下思路,借助于這道題钮蛛,我想到的方法是:我先固定兩個存在的x1鞭缭、x2,然后在兩個x1魏颓、x2上找對應(yīng)相等的每對y1岭辣、y2即可,那么x1甸饱、x2和每對y1沦童、y2這4個點(diǎn)肯定能構(gòu)成矩形。
比如:[[1,3],[3,1],[3,3],[1,3],[1,2]]叹话。
我們發(fā)現(xiàn)只有兩個x:1偷遗、3,然后我們在x為1和3之上去找y驼壶,發(fā)現(xiàn)有兩個相等的y:1氏豌、3,那么答案也就是abs(x2 - x1) * abs(y2 - y1) = 4了热凹。

        int minValue = INT_MAX;
        //x為key泵喘,相同x的y為value
        unordered_map<int, set<int>> pointMap;
        unordered_map<int, set<int>>::iterator mapIterator,tempIterator;
        for (int index = 0; index < points.size(); index ++) {
            pointMap[points[index][0]].insert(points[index][1]);
        }
        mapIterator = pointMap.begin();
        set<int>::iterator setIterator;
//        while (mapIterator != pointMap.end()) {
//            cout<<"key:"<<mapIterator->first<<" ";
//            set<int> numbers = mapIterator->second;
//            setIterator = numbers.begin();
//            while (setIterator != numbers.end()) {
//                cout<<*setIterator<<" ";
//                setIterator ++;
//            }
//            cout<<endl;
//            mapIterator ++;
//        }
        
        mapIterator = pointMap.begin();
       //雙重for循環(huán)固定x1、x2
        for (; mapIterator != pointMap.end(); mapIterator ++) {
            tempIterator = mapIterator;tempIterator ++;
            for (; tempIterator != pointMap.end(); tempIterator ++) {
                int leftX = mapIterator->first;
                int rightX = tempIterator->first;
                //對兩個x對應(yīng)的y進(jìn)行遍歷般妙,找到交集
                set<int> leftYs = mapIterator->second;
                set<int> rightYs = tempIterator->second;
                //現(xiàn)在我們需要從leftYs和rightYs中找到交集
                set<int> unionSet;
                setIterator = leftYs.begin();
                while (setIterator != leftYs.end()) {
                    if(rightYs.find(*setIterator) != rightYs.end()) {
                        unionSet.insert(*setIterator);
                    }
                    setIterator ++;
                }
                //如果沒有兩個數(shù)相等纪铺,則直接下一個循環(huán),說明不存在y1股冗、y2
                if(unionSet.size() < 2) {
                    continue;
                }
                //找到y(tǒng)1霹陡、y2的最小差值
                int minSubValue = INT_MAX;
                for (setIterator = unionSet.begin(); setIterator != unionSet.end(); setIterator ++) {
                    set<int>::iterator temp = setIterator; temp ++;
                    if(temp == unionSet.end()) { break; }
                    minSubValue = min(minSubValue,*temp - *setIterator);
                }
                minValue = min(minValue,minSubValue * abs(leftX - rightX));
            }
        }
        return minValue == INT_MAX ? 0 : minValue;

這個代碼還是很通俗易懂的,當(dāng)然了還有可以優(yōu)化的地方,可以用位運(yùn)算來做烹棉。

后記

數(shù)據(jù)結(jié)構(gòu)攒霹、算法和設(shè)計模式作為軟件開發(fā)的三大基礎(chǔ),做算法也就相當(dāng)于同時練習(xí)了數(shù)據(jù)結(jié)構(gòu)和算法浆洗,意義還是很大的催束。有些算法題看到題目后確實一點(diǎn)思路都沒有,不過不要慌伏社,算法也是一個不斷學(xué)習(xí)的過程抠刺。時間長了,你也就會做了摘昌。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末速妖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子聪黎,更是在濱河造成了極大的恐慌罕容,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件稿饰,死亡現(xiàn)場離奇詭異锦秒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)喉镰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門旅择,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人侣姆,你說我怎么就攤上這事生真。” “怎么了捺宗?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵汇歹,是天一觀的道長。 經(jīng)常有香客問我偿凭,道長,這世上最難降的妖魔是什么派歌? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任弯囊,我火速辦了婚禮,結(jié)果婚禮上胶果,老公的妹妹穿的比我還像新娘匾嘱。我一直安慰自己,他們只是感情好早抠,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布霎烙。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪悬垃。 梳的紋絲不亂的頭發(fā)上游昼,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機(jī)與錄音尝蠕,去河邊找鬼烘豌。 笑死,一個胖子當(dāng)著我的面吹牛看彼,可吹牛的內(nèi)容都是我干的廊佩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼靖榕,長吁一口氣:“原來是場噩夢啊……” “哼标锄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起茁计,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤料皇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后簸淀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓶蝴,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年租幕,在試婚紗的時候發(fā)現(xiàn)自己被綠了舷手。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡劲绪,死狀恐怖男窟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贾富,我是刑警寧澤歉眷,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站颤枪,受9級特大地震影響汗捡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜畏纲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一扇住、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧盗胀,春花似錦艘蹋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宅荤。三九已至,卻和暖如春浸策,著一層夾襖步出監(jiān)牢的瞬間冯键,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工的榛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留琼了,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓夫晌,卻偏偏與公主長得像雕薪,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子晓淀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容