美文网首页
LeetCodeAnswer_with_C++

LeetCodeAnswer_with_C++

作者: theBaldWatcher | 来源:发表于2015-10-27 16:57 被阅读0次

    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;
    }
    

    相关文章

      网友评论

          本文标题:LeetCodeAnswer_with_C++

          本文链接:https://www.haomeiwen.com/subject/pfvxhttx.html