1.29-。。。 數(shù)列

[ 80 questions / 3 ~= 27 a month..ok.. ]

1.29: remove_duplicatesI-III

  • focus on III
class Solution {
public:
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
        if (nums.empty()) return false;
        map<int, int> num2Idx;
        // j...i
        for (int i=0, j=0; i<nums.size(); ++i) {
            if (i-j>k && num2Idx[nums[j]]==j) {
                num2Idx.erase(nums[j++]);
            }    
            auto it=num2Idx.lower_bound(nums[i]-t); 
            if (it!=num2Idx.end() && abs(it->first - nums[i]) <= t) {//it->first <= nums[i]+t) {
                return true;
            }
            if (it!=num2Idx.end())
                cout<<"i: "<<i<<"; abs(it->first - nums[i])"<<it->first<<"-"<<nums[i]<<"="<<abs(it->first - nums[i])<<"?="<<t<<endl;
            num2Idx[nums[i]] = i;
            cout<<-2147483647-2147483647<<endl;
            
        }
        return false;
    }
};

blah

  • sort(it1, it2, comparator: default<, use std::greater<int>() for decending)
  • unordered_set<int> set1(nums1.begin(), nums1.end());

- 349] Intersection of Two Arrays

for look up operation

   vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
       unordered_set<int> set1(nums1.begin(), nums1.end());
       vector<int> ret;
       for (int i : nums2) 
           if (set1.erase(i)) 
               ret.push_back(i);
           
       return ret;
   }

- Longest Increasing Subsequence

  • basic dp: O(n^2)
  • w/ binary search to narrow down where to place each num[curr] O(nlogn)
    試著構(gòu)建LIS array來找規(guī)律
    int lengthOfLIS(vector<int>& nums) {
        int n = nums.size();
        if (!n) return 0;
        vector<int> LIS(n, -1); // stores the actual LIS, initialize [0] to be 1
        int lasti = 0; // end pointer points to last char of LIS
        LIS[lasti] = nums[0];
        
        for (int curr=1; curr<n; ++curr) {
            if (LIS[lasti] < nums[curr]) {
                LIS[++lasti] = nums[curr];
            } else {
                //binary search to find a pos to push: s.t. leftmost pos that nums[pos] > nums[curr]
                int low = 0, high = lasti, mid = -1;
                while (low<high) {
                    mid = low + (high-low)/2;
                    if (LIS[mid] < nums[curr]) {
                        low = mid+1;
                    } else {
                        high = mid;
                    }
                }
                LIS[low] = nums[curr];
            }
        } // end for
        return lasti+1;
    }

- 26] Remove Duplicates from Sorted Array

  • don't forget corner cases
    int removeDuplicates(vector<int>& nums) {
        if (nums.size()<2) return nums.size();
        int writeri=1; // always point at next to write
        for (int readeri=1; readeri<nums.size();  ++readeri) {
            if (nums[readeri-1] != nums[readeri])
                nums[writeri++] = nums[readeri];
        }
        return writeri;
    }

- 88] Merge Sorted Array

  • 因為都要寫到array1,所以只擔心array2后排完的時候
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int writei = m+n-1;
        int i=m-1, j=n-1;
        while (i>=0 && j>=0) 
            nums1[writei--] = nums1[i] > nums2[j]? nums1[i--] : nums2[j--];

        while (j>=0) nums1[writei--] = nums2[j--];
    }

- rotate array

通過不停的交換某兩個數(shù)字的位置來實現(xiàn)旋轉(zhuǎn)


Paste_Image.png
    void rotate(vector<int>& nums, int k) {
        int n = nums.size();
        if (n<2) return;
        k %= n;
       for (int step=0; step<k && starti<n-1; ++step) {
            swap(nums[starti+step], nums[n-k+starti+step]);
        }
        starti += k;
        n -= k;
    }

  • generate random num:
int randNum = rand()%(max-min + 1) + min;

- 384] Shuffle an Array

  • 洗牌算法

2.1,問題
很簡單:給定一個數(shù)組,將其中的元素隨機排列。比如給定數(shù)組arry=>[1,2,3,4,5]。有A5-5種結(jié)果即5!=120種結(jié)果

2.2,解決
也很簡單,如果用白話來說就是:
a,選中第1個元素,將其與n個元素中的任意一個交換(包括第1個元素自己)。這時排序后的第1個元素已經(jīng)確定。
b,選中第2個元素,將其與n-1個元素中作任意一個交換(包括第2個元素自己)。
c,重復上面步驟,直到剩1個元素為止。

1] Two sum I: better

    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> valToIndex;
        for (int i=0; i<nums.size(); ++i) {
            int diff = target-nums[i];
            if (valToIndex.find(diff) != valToIndex.end()) {
                return vector<int> {valToIndex[diff], i};
            }
            valToIndex[nums[i]] = i;
        }
        return vector<int>{};
    }

167] Two Sum II - Input array is sorted

use two pointers to narrow down, but also can use binary search to determine one of the bounds. e.g. find smallest num s.t. num + [0] >=target

53] Maximum Subarray

    int maxSubArray(vector<int>& nums) {
        int n = nums.size();
        int maxSum = nums[0];
        for (int i=1; i<nums.size(); ++i) {
            nums[i] = nums[i-1] < 0? nums[i] : nums[i] + nums[i-1];
            maxSum = max(maxSum, nums[i]);
        }
        return maxSum;
    }

153] Find Minimum in Rotated Sorted Array

  • don't forget when its not rotated
   int findMin(vector<int>& nums) {
        if (nums.empty()) return -1;
        if (nums[0] <= nums[nums.size()-1]) return nums[0];
        for (int starti=0, endi=nums.size()-1; starti<endi; ) {
            if (starti+1 == endi) 
                return min(nums[starti], nums[endi]);
            int midi = (endi - starti)/2 + starti;
            if (nums[starti] < nums[midi]) starti = midi;
            else endi = midi;
        }
        return -1;
    }

80] Remove Duplicates from Sorted Array II

  • how to avoid overwrite self
    int removeDuplicates(vector<int>& nums) {
        if (nums.size()<2) return nums.size();
        int writei = 2;
        for (int readi=2; readi<nums.size(); ++readi) {
            if (nums[readi] != nums[writei-2])
                nums[writei++] = nums[readi];
        }
        return writei;
    }

215] Kth Largest Element in an Array

  • ehhh don't like 1-indexed..
    int findKthLargest(vector<int>& nums, int k) { // k is 1-indexed
        if (k>nums.size() || k<1) return -1;
        priority_queue<int, std::vector<int>, std::greater<int>> minHeap(nums.begin(), nums.begin()+k);
        for (int i=k; i<nums.size(); ++i) {
            if (nums[i]>minHeap.top()) {
                minHeap.pop();
                minHeap.push(nums[i]);
            }
        }  
        return minHeap.top();
    }

81] Search in Rotated Sorted Array II

    int search(vector<int>& nums, int target) {
        if (nums.empty()) return -1;
        int l=0, r=nums.size()-1;
        for (; l<r; ) {
            int mid = l + (r-l)/2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[l] <= nums[mid]) {
                if (nums[l]<=target && target<nums[mid])
                    r = mid -1;
                else 
                    l = mid + 1;
            } else {
                if (nums[mid]<target && target<=nums[r])
                    l = mid + 1; 
                else
                    r = mid - 1;
            }
        }
        return l==r && nums[l]==target? l : -1;
    }

81] Search in Rotated Sorted Array II

設(shè)想一種情形1,1, 1,2,1,1,1,恰好左中右都是1,這時我們 ++左下標,--右下標,為什么這樣我們不會將這個值跳過呢?

  • 多出了不能確定遞增的情況:左=中 或 中=右
    bool search(vector<int>& nums, int target) {
        if (nums.empty()) return -1;
        int l=0, r=nums.size()-1;
        while (l<r) {
            int mid = l+(r-l)/2;
            if (nums[mid] == target) {
                return true;
            } else if (nums[l] < nums[mid]) {
                if (nums[l]<=target && target<nums[mid]) 
                    r = mid -1;
                else l = mid + 1;
            } else if (nums[mid] < nums[r]) {
                if (nums[mid]<target && target<=nums[r])
                    l = mid + 1;
                else 
                    r = mid - 1;
            } else if (nums[l] == nums[mid]) {
                ++l;
            } else {
                --r;
            }
        }
        return l==r && nums[l]==target;
    }

209] Minimum Size Subarray Sum

  • method1: O(n)
    because the left bound moves O(n) times in worst case
    int minSubArrayLen(int s, vector<int>& nums) {
        int minLen = INT_MAX;
        int acc = 0;
        for (int starti=0, endi=0; endi<nums.size(); ) {
            if (acc + nums[endi] >= s) {
                minLen = min(minLen, endi-starti+1);
                acc -= nums[starti];
                ++starti;
            } else {
                acc += nums[endi];
                ++endi;
            }
        }
        return minLen == INT_MAX? 0 : minLen;
    }
  • method2: O(nlogn) using binary search
    idea: keep a sums array that keep track of accumulated sum, search for lower bound for every qualifying upper bound
    // return biggest index i s.t. i<=uppderIndex && [i]<=upperVal
    int lowerBound(vector<int>& v, int upperIndex, int upperVal) {
        // try to find biggest num <= upperVal
        int ret = 0;
        for (int lefti=0, righti=upperIndex; lefti<=righti; ) {
            int midi = lefti + (righti-lefti)/2;
            if (v[midi] > upperVal) {
                righti = midi-1;
            } else {
                ret = max(ret, midi);
                lefti = midi + 1;
            }
        }
        return ret;
    }
    
    int minSubArrayLen(int s, vector<int>& nums) {
        if (nums.empty() || !s) return 0;
        vector<int> sums(nums.size()+1, 0);
        for (int i=1; i<sums.size(); ++i) sums[i] = sums[i-1] + nums[i-1];
        
        int minLen = INT_MAX;
        for (int i=1; i<sums.size(); ++i) {
            if (sums[i]>=s) {
                // find rightmost index j s.t. j<=i, sums[j]<=[i]-s
                int loweri = lowerBound(sums, i-1, sums[i]-s);
                // cout<<"search till ["<<i-1<<"]"<<" for sums[i]-s "<<sums[i]-s<<"--get ["<<loweri<<"] "<<sums[loweri]<<endl;
                int lefti = loweri+1; // easier to understand
                minLen = min(minLen, i-lefti+1);
            }
        }
        return minLen==INT_MAX? 0 : minLen;
    }

152] Maximum Product Subarray

寫的時候分情況考慮了,如果碰到負數(shù),正數(shù),0?想要保證posPro>=0, negPro<=0, 越寫越復雜因為初始什么值?要用上一輪值的時候?
其實每一步把可能答案先算出來,再compare和assign值。加入新值,新最大候選人:
1)最大負數(shù) X 當前負數(shù)
2)最大正數(shù) X 當前正數(shù)
3)當前數(shù)

    int maxProduct(vector<int>& nums) {
        if (nums.empty()) return 0;
        int posPro = nums[0], negPro = nums[0], ret = nums[0];
        for (int i=1; i<nums.size(); ++i) {
            int pro1 = posPro * nums[i];
            int pro2 = negPro * nums[i];
            posPro = max(max(pro1, pro2), nums[i]);
            negPro = min(min(pro1, pro2), nums[i]);
            ret = max(ret, posPro);
        }
        return ret;
    }
  • another method
int maxProduct(int A[], int n) { // store the result that is the max we have found so far int r = A[0]; // imax/imin stores the max/min product of // subarray that ends with the current number A[i] for (int i = 1, imax = r, imin = r; i < n; i++) { // multiplied by a negative makes big number smaller, small number bigger // so we redefine the extremums by swapping them if (A[i] < 0) swap(imax, imin); // max/min product for the current number is either the current number itself // or the max/min by the previous number times the current one imax = max(A[i], imax * A[i]); imin = min(A[i], imin * A[i]); // the newly computed max value is a candidate for our global result r = max(r, imax); } return r;}

[13] Roman to Integer

    int romanToInt(string s) {
        // Ⅰ(1)、X(10)、C(100)、M(1000)、V(5)、L(50)、D(500)
        // if smaller number (I, X, C) is left of bigger number, + bigger number - smaller number
        int ret = 0;
        for (int i=s.size()-1; i>=0; --i) {
            switch (s[i]) {
                case 'I':
                    ret += i+1<s.size() && s[i+1]!='I'? -1 : 1;
                    break;
                case 'X':
                    ret += i+1<s.size() && s[i+1]!='I' && s[i+1]!='V'  && s[i+1]!='X' ? -10 : 10;
                    break;
                case 'C':
                    ret += i+1<s.size() && (s[i+1]=='M' || s[i+1]=='D') ? -100 : 100;
                    break; 
                case 'M':
                    ret += 1000;
                    break;
                case 'V':
                    ret += 5;
                    break;
                case 'L':
                    ret += 50;
                    break;
                case 'D':
                    ret += 500;
                    break;
            }
        }
        return ret;
    }

[322] Coin Change

O(amount*n)

  • instead of init dp arr as -1, use amount+1 as the invalid state, easier to take min later
    int coinChange(vector<int>& coins, int amount) {
        if (amount<0) return -1;
        
        // minCoins[amount] gives min #coins
        vector<int> minCoins(amount+1, amount+1);
        minCoins[0] = 0;
        for (int i=1; i<amount+1; ++i) {
            for (int& coin : coins) {
                // continue if cannot break the change using this coin
                if (i-coin<0) continue;
                minCoins[i] = min(minCoins[i], minCoins[i-coin]+1);
            }
        }
        return minCoins[amount]==amount+1? -1 : minCoins[amount];
    }

quick sort

int partition(vector<int>& v, int l, int r) {
  int pivot = v[(l+r)/2];
  swap(v[l], v[(l+r)/2]);
  int i=l+1, j=r;
  while (i<=j) {
    if (v[i]<pivot) {
      ++i;
    } else if (v[j]>pivot) {
      --j;
    } else {
      if (i<j) swap(v[i++], v[j--]);
    }
  }
  swap(v[i-1], v[l]);
  return i-1;
}

void quickSort(vector<int>& v, int l, int r) {
  if (l>=r) return;
  int pivoti = partition(v, l, r);
  quickSort(v, l, pivoti-1);
  quickSort(v, pivoti+1, r);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,316評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,481評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,241評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,939評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,697評論 6 409
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,182評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,247評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,406評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,933評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,772評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,973評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,516評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,638評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,866評論 1 285
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,644評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,953評論 2 373

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

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗。 張土汪:刷leetcod...
    土汪閱讀 12,762評論 0 33
  • 不支持上傳文件,所以就復制過來了。作者信息什么的都沒刪。對前端基本屬于一竅不通,所以沒有任何修改,反正用著沒問題就...
    全棧在路上閱讀 1,985評論 0 2
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,717評論 18 399
  • ¥開啟¥ 【iAPP實現(xiàn)進入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 6,482評論 0 17
  • 今天,我又聽說了一起壓力型自殺事件。 91年的大學生,在面對職場和人際關(guān)系的問題中壓力無法消解,最終選擇了跳樓。 ...
    耳羽荷閱讀 432評論 0 1