LeetCodeAnswer_with_C++

Array

Summary Ranges

vector<string> summaryRanges(vector<int>& nums) {
    vector<string> res;
    if (nums.empty()){
        return res;
    }

    int nLength = nums.size() ,tail = 0;//use head & tail
    for(int tail = 0; tail < nLength; ){
        int head = nums[tail];//head can be set to nums[i] directly
        while (tail + 1 != nLength && nums[tail + 1] == nums[tail] + 1) 
            tail += 1;

        if(nums[tail] > head)
            res.push_back(to_string(head) + "->" + to_string(nums[tail]));
        else
            res.push_back(to_string(head));

        tail ++;
    }
    return res;
}

Rotate Array

翻转算法:28ms

void rotate(int nums[], int n, int k) {
    k %= n;
    reverse (nums,nums+n-k);
    reverse (nums+n-k,nums+n);
    reverse (nums,nums+n);
}

块交换算法:24ms ,improve 14%

inline void swap(vector<int>& nums,int head1, int head2, int moves){
    int temp ;
    while (moves--){
        temp = nums[head1];
        nums[head1++] = nums[head2];
        nums[head2++] =temp;
    }
}
void rotate(vector<int>& nums, int k) {
    k %= nums.size();
    if (nums.size() < 2 || k == 0 )
        return ;
    //0--left~~k~~right--end,move part is dicided by min(left,right)
    //and the start of right need to be caculated
    //p for the rotate point, be the last one in left
    int left = nums.size() - k, right = k, p = left - 1;
    while(left != right){
        if (left < right){
            swap(nums,p-left+1, p+right - left+1, left);
            right -= left;
        }else{//left > right
            swap(nums,p-left+1, p+1, right);
            left -= right;
        }
    }
    //left == right
    swap(nums, p-left+1, p+1, left);
}

RemoveElements

不能使用swap(如果111112移除1)

int removeElement(vector<int>& nums, int val) {
    int m = 0, nNums = nums.size();
    for (int i = 0; i < nNums;i++){
        if(nums[i] != val)
            nums[m++] = nums[i];
    }
    return m;
}

RemoveDeplicatesFromSortedArray

32ms

int removeDuplicates(vector<int>& nums) {
    if (nums.size() < 2) return nums.size();
    //nums[m] records the begaining of duplicates
    int m = 1;
    for (int i = 1;i < nums.size();i++){
        if (nums[i] != nums[i-1])
            nums[m++] = nums[i];
    }
    return m;
}

PlusOne

vector<int> plusOne(vector<int>& digits) {
    for (auto r = digits.rbegin(); r != digits.rend(); r++){
        if(*r <9){
            *r += 1;
            return digits;
        }//esle
        *r = 0;
    }
    //this means digits is 9...99
    digits[0] = 1;
    digits.push_back(0);
    return digits;
}

Pascal'sTriangle:&

vector<vector<int>> generate(int numRows) {
    vector<vector<int> > res;
    for (int i = 0; i < numRows; i++){
        vector<int> oneLine{1};
        for (int j = 1; j < i; j++){//i>=2, numRows >=3
            oneLine.push_back(res[i-1][j-1] + res[i-1][j]);
        }
        if (i != 0)
            oneLine.push_back(1);
        res.push_back(oneLine);
    }
    return res;
}
vector<int> getRow(int rowIndex) {
    vector<int> res(rowIndex +1);
    res[0] = 1;

    for (int i = 1; i <= rowIndex; i++){
        int mid = i >>1;
        for (int j = mid; j >= 1; j--){
            //mid-(mid-j)=i-j
            res[i-j] = res[j]= res[j]+res[j-1];
        }
        res[i] = 1;//j>0
    }
    return res;
}

MoveZeroes

20ms

void moveZeroes(vector<int>& nums) {
    int nNums = nums.size();
    int index;
    for (int i = 0; i < nNums; i++){
        if(nums[i] != 0){
            swap(nums[index],nums[i]);
            index++;
        }
    }
}

MergeSortedArray

从nums1逆向merge。若m、n中有一个为0,对应数组已耗尽。若耗尽的是nums1,将nums2装到nums1中;若是nums1,则可略过

void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
    m--;n--;
    for (int i = m+n+1; i >= 0 ; i--){
        if (m >=0 && n >=0){
            if(nums1[m] > nums2[n])
                nums1[i] = nums1[m--];
            else
                nums1[i] = nums2[n--];
        }
        else if (n >= 0){//m<0
            while(n>=0) nums1[i--] = nums2[n--];
            return;
        }
        else 
            return;
    }
}

MajorityElement

将nNums替换nums.size()后,从20提升到了16ms。20%

int majorityElement(vector<int>& nums) {
    int major = nums[0],nNums = nums.size();
    short count = 1;
    for (int i = 1; i < nNums;i++){
        if (nums[i] == major)
            count++;
        else{
            if(count >1)
                count--;
            else//count == 1,and count-- == 0
                major = nums[i];
        }
    }
    return major;
}

ContainsDuplicate&

36ms。如果不用unordered_map,使用int[],可以达到20ms,但是要数组长度无法设置。另外一种低效但简单地方法是set之后比较长度是否有缩短。

inline void hashSet(unordered_map<int,int>& map, int i ){ 
    map[i>>5] |= 1<<(i&0x1f);
}
inline bool isInHash(unordered_map<int,int>& map, int i){
    return map[i>>5] & (1<<(i&0x1f));
}
bool containsDuplicate(vector<int>& nums) {
    auto nNums = nums.size();
    unordered_map<int,int> map;
    for(int i = 0; i < nNums; i++){
        if(!isInHash(map,nums[i])){
            hashSet(map,nums[i]);
        }
        else
            return true;
    }
    return false;
}

尝试过使用queue,失败;int[],超时

bool containsNearbyDuplicate(vector<int>& nums, int k) {
    int nNums = nums.size();
    unordered_set<int> pipe;

    for(int i = 0;i < nNums; i++){
        if (i > k) pipe.erase(nums[i-k-1]);
        if (!pipe.insert(nums[i]).second)
            return true;//find
    }
    return false;
}

WordSearch

public:
bool exist(vector<vector<char>>& board, string word) {
    if(board.size() == 0) return false;

    I = board.size(), J = board[0].size();
    for (int i = 0; i < I; i++){
        for (int j = 0; j < J; j++){
            if (isValid(board,word,i,j,0)) return true;
        }
    }
    return false;
}
private:
int I,J;
bool isValid(vector<vector<char>>& board, string &word,int i, int j,int matchLen){
    if (word.size() == matchLen)
        return true;
    if (i < 0 || j < 0 || i == I || j == J)
        return false;
    if (board[i][j] != word[matchLen++])
        return false;
    //matche a letter,forward    
    board[i][j] ^= 0xff;//no letter's ASCII would begin with 1
    bool isvalid = isValid(board,word,i-1,j,matchLen) 
                    ||isValid(board,word,i+1,j,matchLen)
                    ||isValid(board,word,i,j-1,matchLen)
                    ||isValid(board,word,i,j+1,matchLen);
    board[i][j] ^= 0xff;//recover
    return isvalid;
}

UniquePaths &

int uniquePaths(int m, int n) {    
    int dp[n+1] {0};    dp[1] = 1;
    for (int i = 1; i <= m; i++)//i starts at 1
        for (int j = 1; j <= n; j++)
            dp[j] += dp[j-1];//[i,j] = [i-1,j]+[i,j-1]
    return dp[n];
}
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
    if (obstacleGrid.empty()) return 0;
    //dp 添加了1个辅助行和列,元素比obstacle的下标有偏移1
    int m = obstacleGrid.size(), n = obstacleGrid[0].size();
    int dp[n+1] {0};    dp[1] = !obstacleGrid[0][0];
    for (int i = 0; i < m; i++)//i,j是obstacle的下标,不是dp的
        for (int j = 0; j < n; j++){
            if (obstacleGrid[i][j])
                dp[j+1] = 0;
            else dp[j+1] += dp[j];
        }
    return dp[n];
}

TwoSum

vector<int> twoSum(vector<int>& nums, int target) {
    auto sortNums = nums;
    int nNums = nums.size();
    sort(sortNums.begin(),sortNums.end());

    //这里不用for循环二分搜索,采用两段相向查询
    int left = 0, right = nums.size()-1;
    while (true){//一定有答案,所以略去判断
        int sum = sortNums[left] + sortNums[right];
        if (sum == target) break;
        if (sum < target) left++;
        else right--; 
    }

    for (int i = 0; i < nNums; i++){
        if (nums[i] == sortNums[left]){
            left = i;
            break;
        }
    }//逆向搜索,以免nums有重复值
    for (int i = nNums-1; i >=0; i--){
        if (nums[i] == sortNums[right]){
            right =i;
            break;
        }
    }

    //left >right 时,swap(left,right)
    if (left > right) { left^= right; right^= left;  left^= right;}
    return vector<int> {left+1,right+1};
}

Triangle

int minimumTotal(vector<vector<int>>& triangle) {
    int n = triangle.size();
    vector<int> dp(triangle[n-1]);

    for (int i = n-2; i >= 0; i--){
        for (int j = 0; j <= i; j++)
            dp[j] = triangle[i][j] + min(dp[j],dp[j+1]) ;
    }
    return dp[0];
}

Subsets &

外循环为nums时更简洁。外循环为逐条子集的时候,似乎会更快,但是OJ的时间没有变化,故略去。8ms

vector<vector<int>> subsets(vector<int>& nums) {
    sort(nums.begin(),nums.end());
    int nNums = nums.size();
    int nRes = (1<<nNums);
    vector<vector<int> > res(nRes);

    int tempI ;
    for (int i = 0; i < nNums; i++){
        for (int j = 0;j <nRes; j++){
            if ((j>>i)&1)
                res[j].push_back(nums[i]);
        }
    }
    return res;
}

Ⅱ不能使用Ⅰ中的办法。12ms

vector<vector<int>> subsetsWithDup(vector<int>& nums) {
    sort(nums.begin(),nums.end());
    int nNums = nums.size();
    vector<vector<int>> subsets{{}};//不能省略,见nSub
    vector<int> oneSub;


    for (int i = 0;i < nNums; ){
        int count = 1;
        while (i+count < nNums && nums[i+count] == nums[i] )
            count ++;
        int nSub = subsets.size();
        for (int j = 0; j < nSub; j++){
            oneSub = subsets[j];
            for (int k = 0; k < count; k++){
                oneSub.push_back(nums[i]);
                subsets.push_back(oneSub);
            }
        }
        i += count;
    }
    return subsets;
}

SpiralMatrix & Ⅱ

CleanCode 第35题

vector<int> spiralOrder(vector<vector<int>>& matrix) {
    vector<int> result;
    if (!matrix.size() || !matrix[0].size()) return result;
    int nrow = matrix.size(), ncol = matrix[0].size();

    int row = 0,col = -1;//每一个循环假定从左方驶入
    while (true){
        int i ;
        for (i = 0; i < ncol; i++)
            result.push_back(matrix[row][++col]);
        if (--nrow == 0) break;

        for (i = 0; i < nrow; i++)
            result.push_back(matrix[++row][col]);
        if (--ncol == 0) break;

        for (i = 0; i < ncol; i++)
            result.push_back(matrix[row][--col]);
        if (--nrow == 0) break;

        for (i = 0; i < nrow; i++)
            result.push_back(matrix[--row][col]);
        if (--ncol == 0) break;
    }
}
vector<vector<int>> generateMatrix(int n) {
    vector<vector<int> > result(n,vector<int>(n));
    if (n == 0) return result;
    int row = 0, col = -1;
    int walker = 1;

    while (true){
        for (int i = 0; i < n; i++)
            result[row][++col] = walker++;
        if (--n == 0) break;
        for (int i = 0; i< n; i ++)
            result[++row][col] = walker++;

        for (int i = 0; i < n; i++)
            result[row][--col] = walker++;
        if (--n == 0) break;
        for (int i = 0; i < n; i++)
            result[--row][col] = walker++;
    }
    return result;
}

SortColors

注意,异或的swap不能作用于相同的数

void sortColors(vector<int>& nums) {
    int left = 0, right = nums.size()-1;

    for (int i = 0; i <= right; ){
        switch (nums[i]){
            case 0: {// if(nums[i] == 0) {//swap
                swap(nums[i++],nums[left++]);
                break;
            }
            case 2:{//else if ( nums[i] == 2)
                swap(nums[i],nums[right--]);//右边没检查过,不能i++跳过
                break;
            }
            default: i++;
        }
    }
}

SetMatrixZeroes

第二个for循环想调优一下,然并卵

    if (!matrix.size() ||!matrix[0].size()) return ;
    int nrow = matrix.size(), ncol = matrix[0].size();
    bool setColOne = false;//第一列是否置0要排除来自行的干扰

    for (int i = 0; i < nrow; i++){
        if (!setColOne && !matrix[i][0]) setColOne = true;
        for (int j = 1; j < ncol;j++){
            if (!matrix[i][j]){
                matrix[0][j] = 0;
                matrix[i][0] = 0;
            }
        }
    }
    //逆序,因为信息在首行/列
    for (int i = nrow-1; i >=0 ; i--){
        bool tempRow0 = matrix[i][0] == 0;//for speed up
        for (int j = ncol - 1; j >=1 ;j--){
            if (tempRow0 || !matrix[0][j])//!matrix[i][0]
                matrix[i][j] = 0;
        }
        if (setColOne) matrix[i][0] = 0;
    }
}

SearchInsertPosition

最简单是用lower_bound。自己写一个二分搜索也一样。都是8ms

int searchInsert(vector<int>& nums, int target) {
    return lower_bound(nums.begin(),nums.end(),target)- nums.begin();
}
int searchInsert(vector<int>& nums, int target) {
    int nNums = nums.size();
    if (!nNums) return 0;
    if (nums[nNums-1] < target) return nNums;

    int left = 0, right = nNums -1;
    while (left < right){
        int middle = left+right>>1;//(left>>1)+(right-left>>1) 
        if (nums[middle] < target)
            left = middle+1;
        else 
            right = middle;
    }
    //if target > nums[nNums-1], it has already been returned
    return right;
}

SearchForARange

不想写二分搜索,直接用std

vector<int> searchRange(vector<int>& nums, int target) {
    vector<int> result{-1,-1};
    if (nums.size() && binary_search(nums.begin(),nums.end(),target)) {
        result[0] = lower_bound(nums.begin(),nums.end(),target) - nums.begin();
        result[1] = upper_bound(nums.begin(),nums.end(),target) - nums.begin()-1;

    }
    return result;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,743评论 0 33
  • 1. Two Sum 用hash可以得到O(n)时间的解法,用python中的enumerate函数,可以获得元素...
    Morphiaaa阅读 436评论 0 0
  • 要编写一段脚本,你需要将目标分解成一系列的任务 可能需要设计函数和IO,即API,然后分解成一个一个的完成任务所需...
    历奇阅读 186评论 0 0
  • (十一)有心就行夏妍把学期总结报告上交之后,就立马在网上订了去大理的票。前几年工作所攒 的积蓄全都投到建校舍上去了...
    及己阅读 281评论 2 3
  • 昨天刚下班的时候,苏老打来电话。还未接通的那一刹那,我猜想或许是他将要出差深圳,提前约我面“基”。接通后才反应过来...
    南方锈才阅读 738评论 0 2