2018年4月16日 星期一

[67] Add Binary

吸加加的string好方便QQ
不過還是寫的很醜
sign

Add Binary
class Solution {
public:
    string addBinary(string a, string b) {
        int lenA = a.length();
        int lenB = b.length();
        string ret;
        int i,j, flag = 0;
        for(i=lenA,j=lenB;(i>0 || j>0);i--,j--)
        {
            int anum = 0,bnum = 0;
            if (i>0)
                anum = a[i -1] - '0';
            if (j>0)
                bnum = b[j -1] - '0';

            int tmp = flag + anum + bnum;
            if (tmp > 1)
            {
                flag = 1;
                tmp -=2;
            }
            else
                flag = 0;
            ret = to_string(tmp) + ret;


        }
        if (flag>0)
            ret = "1" + ret;

        return ret;
    }
};

[20260710] 更新
奇怪別人寫就是比較漂亮 ~—~
#define max(a,b) (a>b)?(a):(b)
void reverse(char *a, char *b){
char tmp = *a;
*a=*b;
*b=tmp;
}

char* addBinary(char* a, char* b) {
int l1 = strlen(a);
int l2 = strlen(b);
int longer= max(l1, l2);
int carry = 0;
char *ret = calloc(longer+2, sizeof(char));//for additional carry & ending so it's longer +1 +1
int idx = 0;
while (longer>0){
int v1=0;
int v2=0;
if (l1-1>=0)
v1= a[--l1]-'0';
if (l2-1>=0)
v2= b[--l2]-'0';
//printf("%d + %d\n", v1, v2);
int sum = carry+v1+v2;
carry = (sum>1)? 1: 0;
ret[idx++]= ((sum& 0x1)==1)? '1' :'0';
longer--;
}
if (carry>0)
ret[idx++]='1';
//printf("idx %d carry %d\n", idx,carry);
for (int i=0; i<idx/2;i++)
reverse(&ret[i], &ret[idx-1-i]);
return ret;
}

看來while 可以改成 l1>0 || l2>0 || carry 結果又改出無窮回圈 囧
#define max(a,b) (a>b)?(a):(b)
void reverse(char *a, char *b){
char tmp = *a;
*a=*b;
*b=tmp;
}

char* addBinary(char* a, char* b) {
int l1 = strlen(a);
int l2 = strlen(b);
int longer= max(l1, l2);
int carry = 0;
char *ret = calloc(longer+2, sizeof(char));//for additional carry & ending so it's longer +1 +1
int idx = 0;
while (l1>0 || l2>0 || carry){
int v1=0;
int v2=0;
if (l1-1>=0)
v1= a[--l1]-'0';
if (l2-1>=0)
v2= b[--l2]-'0';
int sum = carry+v1+v2;
carry = (sum>1)? 1: 0;
ret[idx++]= ((sum& 0x1)==1)? '1' :'0';
}
for (int i=0; i<idx/2;i++)
reverse(&ret[i], &ret[idx-1-i]);
return ret;
}
[20260709] 更新
有一點懶得修! 這個算是復健題XD 輸入小的時候應該是對的~
但長度一長就一定是錯的要重寫~就先貼下吧. 沒想到當年我竟然是用C++寫的XD

int str2int(char* s1, int len){
int ret=0;
for (int i=0; i<len;i++)
{
ret = (ret<<1) + (s1[i] & 0x1);
}
// printf("ret %d\n",ret);
return ret;
}
#define STRLEN INT_MAX
void swap(char *a, char *b){
char tmp = *a;
*a = *b;
*b = tmp;
return;
}

char* int2str(int val){
char *ret = calloc (STRLEN,sizeof(char));
int idx = 0;
//printf("int2str val %d\n",val);
while (val>0)
{
if (val&0x1 == 1)
ret[idx++]='1';
else
ret[idx++]='0';
val= val>>1;
//printf("int2str idx %d, [%c]\n",idx, ret[idx-1]);
}
//printf("int2str idx(len) %d\n",idx);
char *reverse= calloc(idx+1, sizeof(char));
// char *reverse = (char*) realloc(ret, idx*sizeof(char));
for (int i=0; i<idx; i++)
reverse[idx-i-1]= ret[i];
#if 0
printf("int2str idx %d, strlen %d\n",idx, strlen(reverse));
for (int i=0; i<idx/2; i++)
{
swap(&reverse[i], &reverse[idx-i]);
}
#endif
if (idx==0)
return "0";
return reverse;
}

char* addBinary(char* a, char* b) {
int l1 = strlen(a);
int l2 = strlen(b);
printf("l1 %d l2 %d\n",l1,l2);
int sum = str2int(a,l1) + str2int(b,l2);
//printf("sum %d\n",sum);

return int2str(sum);
// return NULL;
}

2018年4月14日 星期六

[35] Search Insert Position

給一個sorted array和一個數字,
回傳這個數字在array裡的index
如果不存在, 則回傳依大小把它加進去的話它應該是多少index
吸加加到底是什麼
我現在好迷惘啊~~~(滾來滾去滾來滾去)

Search Insert Position
class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int i, len = nums.size();
        for (i=0;i<len;i++)
            if (nums[i] >= target)
                break;
        return i;
    }
};

[20251025 更]
什麼原來我當時是用C++寫嗎~_~
結果還是搞不懂return value 應該是什麼啊啊啊啊啊~(抱頭)
在這個題目裡, 兩種return 是一樣的。
while 給它等於,  mid 給它加減一。

int searchInsert(int* nums, int numsSize, int target) {
int l=0;
int r = numsSize-1;
while(l<=r)
{
int mid = l+(r-l)/2;
if (nums[mid]== target)
return mid;
if (nums[mid]<target)
l=mid+1;
if (nums[mid]>target)
r=mid-1;
}
return l;
return r+1;
}

2018年3月9日 星期五

[94] Binary Tree Inorder Traversal

難得寫的還算精準
一回神發現題目還有一行:
Note: Recursive solution is trivial, could you do it iteratively?
真是討厭呢XD
不管~以後再說吧Orz
據說要用iterative的方法要用stack這樣.
你知道用C寫stack 且內容物是linked list 有多麻煩嗎有多麻煩嗎!!!(逼近出題者)
(啊不就是要考你嗎XD)
(啊網路上現成的lib 那麼多, 是威什麼一定要我在面試的短短幾十分鐘之內寫一份出來啦!!! 你上班難道都不用copy paste嗎有現成的難道你不用而硬要自己寫一個嗎?!)(是在抱怨什麼辣XD)(我絕對不是因為剛剛吃了一個難吃的煎鍋鬆餅等了超久花我兩百五結果超難吃而在遷怒.)(分明就是XD!)

Binary Tree Inorder Traversal
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Return an array of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
void getValue(int* ret, int *size, struct TreeNode* ptr){
    if (ptr==NULL)
        return;
    getValue(ret, size, ptr->left);  
    ret[(*size)++] = ptr->val;
    getValue(ret, size, ptr->right);
}

int* inorderTraversal(struct TreeNode* root, int* returnSize) {
    *returnSize = 0;
    if (root==NULL)
        return NULL;
    int* ret = malloc(sizeof(int)*(10000));
    int retSize = 0;
    struct TreeNode* ptr = root;
    getValue(ret, &retSize, ptr);
    *returnSize = retSize;
    return ret;
}


20241007 update 覺得自己不會寫扣了QQ


int func(struct TreeNode* root, int *ret , int idx)
{
    if (root == NULL)
        return idx;
    idx = func(root->left, ret, idx);
    ret[idx++]=root->val;
    idx = func(root->right, ret, idx);
    return idx;
}

int* inorderTraversal(struct TreeNode* root, int* returnSize){
    int *ret = calloc(1000, sizeof(int));
    *returnSize = func(root, ret, 0);;
    return ret;
}

2018年3月7日 星期三

[78] Subsets

更新吸加加版本:
class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> ret(1,vector<int>());
        for (auto &i : nums)
        {
            int len = ret.size();          
            for (int j=0;j < len;j++)
            {
                ret.push_back(ret[j]);
                ret.back().push_back(i);
            }
        }
        return ret;
    }
};
太久沒寫吸加加, 原來我其實不會吸加加QQ
vector 是什麼QQ vector of vector 是什麼 QQ
auto也是第一次看到, 我是上古時代的人嗎XD
想嘗試用auto, 怎麼一直寫不粗乃!
原來第二個for有新增element , 長度會改變,
需要在動它之前記錄原本長度才刻以
以上.

***更新分隔線更新分隔線***

給一個array列出它所有subset的可能
是一個用講的很簡單, 用C寫卻半天寫不出來的東西(該不會只有我XD!)
弄半天才發現自己malloc的觀念還是亂七八糟的Orz
然後感覺calloc 很好用啊為什麼我以前都沒用呢 (?)(問誰呢 XD)
看來之前幾題用到int ** columnSizes的大概都用錯了 QQ
哭哭~這幾天趕快來複習修正一下QQ

Subsets
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *columnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** subsets(int* nums, int numsSize, int** columnSizes, int* returnSize) {
    int retSize = pow(2,numsSize);

    *returnSize = retSize;
    int** ret = malloc(sizeof(int*)* (retSize));
    int curSize = 0,i,j;
    for (i=0;i<retSize;i++)
    {
        ret[i] = malloc(sizeof(int)*(numsSize+1));
#if 1
        *columnSizes = malloc(sizeof(int)*retSize);
        memset(*columnSizes,0,sizeof(int)*retSize);
#else
        *columnSizes = calloc(retSize, sizeof(int));
#endif
    }
    curSize++;
    if (retSize>1)
        ret[curSize++][(*columnSizes)[1]++] = nums[0];

    for (i=1;i<numsSize;i++)
    {
        int nowSize = curSize;
        for(j=0;j<nowSize;j++)
        {
            memcpy(ret[nowSize+j],ret[j],sizeof(int) * (*columnSizes)[j]);
            (*columnSizes)[nowSize+j] = (*columnSizes)[j];
            ret[curSize++][(*columnSizes)[nowSize+j]++] = nums[i];          
        }
    }
    return ret;
}


2018年3月6日 星期二

[130] Surrounded Regions

我覺得我沒懂 囧
真是神秘的題目
給一個只有X跟O的矩陣
如果O都有被X包圍住, 把O改成X
邊界的O屬於沒有被包住, 維持O.

大家都提到了BFS跟DFS
我只有掃過來掃過來還是各種漏掉 囧
總之如果O沒有被包住, 都是從邊界來的 ;
所以重點就是從邊界開始, 如果有O , 先把它改成別的例如Y
並且檢查它的上下左右如果也有O, 一樣改成Y
如果那個O要被改成Y了, 新的Y的上下左右也要檢查,
有微遞迴的fu .

最後再把剩下的O全部改成X , 被改成Y的再全部改回O
就會是答案了..............
真是囉哩囉唆呀~唉
(重點是為什麼我都想不到也寫不對呢 ~?!QQ)

void check(char** board,int i,int j,int row,int col){
    if (i<0 || j<0 || i+1 >row || j+1 > col)
        return;
    if(board[i][j]=='O')
    {
        board[i][j]='0';
        check(board,i-1,j,row,col);
        check(board,i,j-1,row,col);
        check(board,i+1,j,row,col);
        check(board,i,j+1,row,col);
    }
}

void solve(char** board, int boardRowSize, int boardColSize) {
    int i,j;
    for(j=0;j<boardColSize; j++)
    {      
        check(board,0,j,boardRowSize,boardColSize);
        check(board,boardRowSize-1,j,boardRowSize,boardColSize);
    }
 
    for(i=0; i<boardRowSize;i++)
    {
        check(board,i,0,boardRowSize,boardColSize);
        check(board,i,boardColSize-1,boardRowSize,boardColSize);
    }
    for(i=0; i<boardRowSize;i++)
        for(j=0;j<boardColSize; j++)
        {
            if (board[i][j]=='O')
            {
                board[i][j] = 'X';
            }                      
        }
    for(i=0; i<boardRowSize;i++)
        for(j=0;j<boardColSize; j++)
        {
            if (board[i][j]=='0')
            {
                board[i][j] = 'O';
            }                      
        }
}

2018年3月5日 星期一

[16] 3Sum Closest

和下面那題差不多 (比樓下)
只是把三個加起來等於零的部分,
改成給一個target值, 要找出相加最接近這個target 值的 3sum
把比對條件改一改就寫完了
算是寫一題賺兩題的概念 XD

3Sum Closest
int compare(const void *a, const void *b)
{
    return (*(int *)a - *(int *)b);
}

int threeSumClosest(int* nums, int numsSize, int target) {
        if (numsSize < 2)
        return NULL;
    qsort(nums,numsSize,sizeof(int),compare);  
    int i,j,k;
    int ret = target;
    int closet = INT_MAX;
    for(i=0;i<numsSize;i++)
    {
        if(i>0 && nums[i]==nums[i-1])
            continue;
        for(j=i+1,k=numsSize-1;j<k;)
        {
            int sum = nums[i]+nums[j]+nums[k] ;
            int diff = abs(sum - target);
            if (diff < closet)
            {
                closet = diff;
                ret = sum;
            }
            if (sum == target)
                return sum;
            else if(sum < target)
            {
                while(j<k && nums[j]==nums[j+1])
                    j++;
                j++;
            }
            else if (sum > target)
            {
                while(j<k && nums[k]==nums[k-1])
                    k--;
                k--;
            }
        }
    }
    return ret;
}

[15] 3Sum

找加起來等於零
且不可重覆
非常醜我知道 囧
但總之還是先放個初版Orz

3Sum
/**
 * Return an array of arrays of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
int compare(const void *a, const void *b)
{
    return (*(int *)a - *(int *)b);
}

int** threeSum(int* nums, int numsSize, int* returnSize) {
    if (numsSize < 2)
        return NULL;
    qsort(nums,numsSize,sizeof(int),compare);  
    int i,j,k;

    int **ret = malloc(sizeof(int *) * (numsSize*30));
    *returnSize = 0;
    for(i=0;i<numsSize;i++)
    {
        for(j=i+1,k=numsSize-1;j<k;)
        {
            int sum = nums[i]+nums[j]+nums[k] ;
            if(sum < 0)
                j++;
            else if (sum > 0)
                k--;
            else
            {
                int index = *returnSize;
                bool same = false;
                for(int check = index-1; check >=0; check--)
                {
                    if (nums[i]<ret[check][0])
                        break;
                    if (nums[i]==ret[check][0] && nums[j]==ret[check][1] && nums[k]==ret[check][2])
                    {
                        same = true;
                        break;
                    }
                }
                if (same)
                {
                    j++;
                    k--;
                    continue;
                }
                ret[index] = malloc (sizeof(int)*3);
                ret[index][0] = nums[i];
                ret[index][1] = nums[j];
                ret[index][2] = nums[k];
                *returnSize += 1;
                j++;
                k--;
            }
        }
    }
    return ret;
}

但很奇怪後來看別人和我的笨版本差不多意思的卻快很多
為什麼呢 XD
不想研究了 XD
但總之重覆的可以跳過
不曉得為什麼一開始我把重覆的跳過一直不對
所以才弄了笨方法
唉感覺沒天份
以下是跳過重覆的版本
/**
 * Return an array of arrays of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
int compare(const void *a, const void *b)
{
    return (*(int *)a - *(int *)b);
}

int** threeSum(int* nums, int numsSize, int* returnSize) {
    if (numsSize < 2)
        return NULL;
    qsort(nums,numsSize,sizeof(int),compare);  
    int i,j,k;

    int **ret = malloc(sizeof(int *) * (numsSize*30));
    *returnSize = 0;
    for(i=0;i<numsSize;i++)
    {
        if(i>0 && nums[i]==nums[i-1])
            continue;
        for(j=i+1,k=numsSize-1;j<k;)
        {
            int sum = nums[i]+nums[j]+nums[k] ;
            if(sum < 0)
            {
                while(j<k && nums[j]==nums[j+1])
                    j++;
                j++;
            }
            else if (sum > 0)
            {
                while(j<k && nums[k]==nums[k-1])
                    k--;
                k--;
            }
            else
            {
                int index = *returnSize;
                ret[index] = malloc (sizeof(int)*3);
                ret[index][0] = nums[i];
                ret[index][1] = nums[j];
                ret[index][2] = nums[k];
                *returnSize += 1;
                while(j<k && nums[j]==nums[j+1])
                    j++;              
                j++;
                while(j<k && nums[k]==nums[k-1])
                    k--;
                k--;
            }
        }
    }
    return ret;
}

結果修了一下比對的順序, "等於"先做,
然後就笨方法也可以得到很快的結果了 = =
覺得瞎XD
int compare(const void *a, const void *b)
{
    return (*(int *)a - *(int *)b);
}

int** threeSum(int* nums, int numsSize, int* returnSize) {
    if (numsSize < 2)
        return NULL;
    qsort(nums,numsSize,sizeof(int),compare);  
    int i,j,k;

    int **ret = malloc(sizeof(int *) * (numsSize*10));
    *returnSize = 0;
    for(i=0;i<numsSize;i++)
    {
        for(j=i+1,k=numsSize-1;j<k;)
        {
            int sum = nums[i]+nums[j]+nums[k] ;
            if (sum==0)
            {
                int index = *returnSize;
                bool same = false;
               
                for(int check = index-1; check >=0; check--)
                {
                    if (nums[i]>ret[check][0])
                        break;
                    else if (nums[i]==ret[check][0] && nums[j]==ret[check][1] && nums[k]==ret[check][2])
                    {
                        same = true;
                        break;
                    }
                }
                if (same)
                {
                    j++;
                    k--;
                    continue;
                }
                ret[index] = malloc (sizeof(int)*3);
                ret[index][0] = nums[i];
                ret[index][1] = nums[j];
                ret[index][2] = nums[k];
                *returnSize += 1;
                j++;
                k--;
            }              
            else if(sum < 0)
                j++;
            else if (sum > 0)
                k--;
        }
    }
    return ret;
}

2018年3月4日 星期日

[146] LRU Cache (TBC)

神秘!!!
竟然又過了!!!
當然效能並不是太好
但似先這樣就好XD
我這個人最不強求了!!!
(問題是別人要求呀哭哭XD)

設計一個 LRU Cache
讓先被insert進去的會最先被取代
如果它有被touch過, 則時間要更新
另外key可以改掉value , 也就是key 1 可以先設個2 , 再 key 1 設個 3,
這時get key 1會得到3而不是2 (感覺很像廢話 XD)
TBC here~ 大概要弄個 first in first out的 queue
讓時間最前面的在head (或linked list)
降子拿掉的時候只要 O(1)
不過時間更新的時候需要重排(麻煩XD)
又似乎需要弄個hash again
(假裝沒看見題目上寫的: Could you do both operations in O(1) time complexity?)
反正今天先這樣XD 收工!

LRU Cache
typedef struct {
    int key;
    int value;
    int time;
} LRUCache;
static unsigned int size = 0;
static unsigned long time = 0;
LRUCache* lRUCacheCreate(int capacity) {
    size = capacity;
    LRUCache* myCache = malloc (sizeof (LRUCache) * capacity);
    for(int i=0;i<size;i++)
    {
        myCache[i].key = -1;
    }
    return myCache;
}

int lRUCacheGet(LRUCache* obj, int key) {
    for(int i=0;i<size;i++)
    {
        if(obj[i].key == key)
        {
            obj[i].time = time++;
            return obj[i].value;
        }
    }
    return -1;
}

void lRUCachePut(LRUCache* obj, int key, int value) {
    int time_min = INT_MAX;
    int drop_index = -1;
    for(int i=0;i<size;i++)
    {
        if(obj[i].key < 0 || obj[i].key == key)
        {
            obj[i].key = key;
            obj[i].value = value;
            obj[i].time = time++;
            return;
        }
        else if (time_min > obj[i].time)
        {
            time_min = obj[i].time;
            drop_index = i;
        }
    }

    obj[drop_index].key = key;
    obj[drop_index].value = value;
    obj[drop_index].time = time++;
 
}

void lRUCacheFree(LRUCache* obj) {
    free(obj);
}

/**
 * Your LRUCache struct will be instantiated and called as such:
 * struct LRUCache* obj = lRUCacheCreate(capacity);
 * int param_1 = lRUCacheGet(obj, key);
 * lRUCachePut(obj, key, value);
 * lRUCacheFree(obj);
 */

[3] Longest Substring Without Repeating Characters

不敢相信!!!
竟然沒寫很久就Accepted了 !!!
感人!!!
找一個字串裡面, 不重覆字元的最長子字串的長度
substring 不等於 subsequence
所以 pababcd 最長是 abcd長度 4
而不是 pabcd長度 5
因為 pabcd 只是subsequence而已, 並不是 substring


Longest Substring Without Repeating Characters
int max (int a, int b){
    return (a>b)? a: b;
}

int lengthOfLongestSubstring(char* s) {
    int len = strlen(s);
    if (len<=1)
        return len;
    int ascii[128];
    int i,tmp, ret=0, start=0, end=len;
    for(i=0;i<128;i++)
        ascii[i]= -1;

    for(i=0;i<len;i++)
    {
        if (ascii[s[i]] >= 0)
        {
            end = i;
            tmp = end - start;
            if (tmp > ret)
                ret = tmp;
            start = max(ascii[s[i]] +1 , start);
        }
        ascii[s[i]] = i;
    }
    end = len-1;
    tmp = end - start + 1;
    if (tmp > ret)
        ret = tmp;

    return ret;
    
}

結果我2022年11月13號回來寫了一個什麼呢? XD
int lengthOfLongestSubstring(char * s){
int hash[128];
int ret=0;
for (int i=0;i<strlen(s);i++)
{
memset(hash,0, sizeof(int)*128);
hash[s[i]]++;
int count=1;
for (int j=i+1; j<strlen(s);j++)
{
if (hash[s[j]] >0)
break;
else
{
hash[s[j]]++;
count++;
}
}
if (count > ret)
ret = count;
}
return ret ;
}


[20240216]
沒想到2024年又回來寫了XD 漫漫長路啊~(痛哭)
2022年寫的算是暴力解(吧)這次寫的算是sliding window還是two pointers呢?!
雖然好像有長進但其實寫不出來 XD 考慮不周啊QQ
當右邊出現"已出現過的字元",左邊的index 要一直移動到該字元只剩一個為止!
而不是只移動一個!冷靜想想也是QQ 我很笨~屋屋屋

int max (int a, int b){
return (a>b)? a: b;
}

int lengthOfLongestSubstring(char* s) {
int *hash = calloc (128, sizeof(int));
int len = strlen(s);
if (len <=1)
return len;

int l=0,r=1;
hash[s[0]-' ']++;
int ret = 1;
while (r<len)
{
hash[s[r]-' ']++;
while (hash[s[r]-' ']>1)
{
hash[s[l]-' ']--;
l++;
}
ret = max(ret,r-l+1);
//printf("ret: %d %d %d\n",l,r, ret);
r++;
}
return ret;
}


[20250930]
雖然是過了....但是我退步了吧Orz 又寫出了垃圾啊屋屋屋

int lengthOfLongestSubstring(char* s) {
int len = strlen(s);
if (len <=1)
return len;
int l=0;
int r = l+1;
int ret=0;
int *hash = calloc (128, sizeof(int));
hash[s[l]]++;
while (r<len)
{
//printf("%d %d\n", l,r);
if (hash[s[r]]==0)
{
hash[s[r++]]++;
if (r-l >ret)
ret= (r-l);
}
else
{
while (s[l]!=s[r])
{
hash[s[l]]--;
l++;
}
hash[s[l]]--;
l++;
}
}
return ret;
}


[84] Largest Rectangle in Histogram

找柱狀圖的最大面積
其實我的腦中一片空白 囧
我連暴力法都不會寫了Orz
大意是整個array跑一遍, 每次找出它的第一個比它小的左邊, 跟第一個比它小的右邊,
將右減左減一當做寬,它自己當做高, 算出它可以擁有的最大面積,
每個item都算出自己的最大面積之後, 再回傳全部裡面的最大的.

看起來是可以用的, 不過不夠快 :
Largest Rectangle in Histogram
int largestRectangleArea(int* heights, int heightsSize) {
    if (heights==NULL || heightsSize<1)
        return 0;
    else if (heightsSize == 1)
        return heights[0];
    int right[heightsSize];
    int left[heightsSize];
    int i,j, k, max =INT_MIN;

    for(i=0;i<heightsSize;i++)
    {
        left[i]=-1;
        for(j=i;j>=0;j--)
        {
            if(heights[j]<heights[i])
            {
                left[i]=j;
                break;
            }
        }

        right[i]=heightsSize;
        for(k=i;k<heightsSize;k++)
            if(heights[k]<heights[i])
            {
                right[i]=k;
                break;
            }

        int area = (right[i]-left[i]-1)*heights[i];
        if (area > max)
            max = area;
    }

    return max;
}

然後就是說用同樣的精神,
只是在找出左邊的第一個最小和右邊的第一個最小的這個部分,
用stack來完成.
每一個item會進去stack一次,
如果stack是空的, push進去;
如果目前的item 比stack的top 大, 也push進去;
如果目前的item 比stack的top 小, 那目前item的index可以當做右邊第一個最小,
stack的top 的value是我們的高, stack top的前一個的index 是左邊第一個做小,
如此可以算出stack top 可以有的最大面積.
算完把它pop掉, stack的top會更新, 用新的top來看目前的item 要被push進去,
還是要來算新的top的面積, 直到做完.

typedef struct _stack{
    int value;
    int index;
} stack;

int largestRectangleArea(int* heights, int heightsSize) {
    if (heights==NULL || heightsSize<1)
        return 0;
    stack myStack[heightsSize];
    int i, head=-1, max = INT_MIN;

    for(i=0;i<heightsSize;i++)
    {
        if (head < 0 || heights[i] >= myStack[head].value)
        {
            myStack[++head].value = heights[i];
            myStack[head].index = i;
        }
        else
        {
            while(head >= 0 && heights[i]<myStack[head].value)
            {
                int index = (head-1)>=0 ? (myStack[head-1].index) : -1;
                int area = (i- index -1) * myStack[head--].value;
                if (area > max)
                    max= area;
            }
            myStack[++head].value = heights[i];
            myStack[head].index = i;
         
        }
    }
    while(head >= 0)
    {
        int index = (head-1)>=0 ? (myStack[head-1].index) : -1;
        int area = (i- index -1) * myStack[head--].value;
        if (area > max)
            max= area;
    }
    return max;
}
這一題可以拿來做[85] Maximal Rectangle (比樓下樓下樓下)
每行row 先往上算出它的 height (在這行row當做基底時, 每一個column往上看有幾個連續的 1 )
如此每行row 都可以套用Largest Rectangle in Histogram 找出它當下的最大面積
最後再回傳每行row最大面積的最大面積(跳針XD).