leetcode 中等题(部分三)

A:数组类
53 Maximum Subarray
从一个数组中找到连续的一个子数组,使得相加的和最大

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int i=0;
        int max =INT_MIN;
        int sum = 0;
        while(i<nums.size()&&nums[i]<0){
            max = max>nums[i]?max:nums[i];  
            sum = (sum+nums[i])>nums[i]?(sum+nums[i]):nums[i];
            i++;
        } 
        for(;i<nums.size();i++){
            if(nums[i]>=0){
                if(sum<0) sum = nums[i];
                else sum = sum + nums[i];
                max =max>sum?max:sum;
            }else{
                sum = sum + nums[i];
                if(sum<0) sum = nums[i];
            }
        }
        return max =max>sum?max:sum;
    }
};

300. Longest Increasing Subsequence
(Given an unsorted array of integers, find the length of longest increasing subsequence)
[10, 9, 2, 5, 3, 7, 101, 18],The longest increasing subsequence is [2, 3, 7, 101]

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
    vector<int> res;
    for(int i=0; i<nums.size(); i++) {
        auto it = std::lower_bound(res.begin(), res.end(), nums[i]);
        if(it==res.end()) res.push_back(nums[i]);
        else *it = nums[i];
    }
    return res.size();
}

81. Search in Rotated Sorted Array II

class Solution {
public:
    bool search(vector<int>& nums, int target) {
        int left =0,right = nums.size()-1;
        int tmp_left =0,tmp_right=0;
    // 这里相对上一道问题,多了个过滤的过程,过滤后,重新设定了左右两个端点的位置
        while(left+1<=right&&nums[left+1]==nums[left]) left++;
        while(right-1>=left&&nums[right-1]==nums[right]) right--;
        tmp_left =left;tmp_right=right;
        
        while(left<right){
            int mid = left+(right-left)/2;
            if(nums[mid]>nums[right]) left=mid+1;
            else right = mid;
        }
        
        int pivot = left;
        if(target<nums[tmp_left]){
            left = pivot;
            right = tmp_right;
        }else if(target>nums[tmp_left]){
            left = tmp_left;
            right = pivot==tmp_left?tmp_right:pivot-1;
        }else if(target==nums[tmp_left]) return true;

        while(left<right){
            int mid = left+(right-left)/2;
            if(nums[mid]==target) return true;
            if(nums[mid]>target) right=mid-1;
            if(nums[mid]<target) left=mid+1;
        }
        if(left<nums.size()&&nums[left]==target) return true;
        return false;
    }
};

C:二叉树类型
199. Binary Tree Right Side View
(给一棵二叉树,想像你站在右边看这课树,返回你从头结点到尾结点所能看到的所有结点的值)

class Solution {
public:
    queue<TreeNode*> q1;
    vector<int> res;
    void help(){
        while(!q1.empty()){
            int size = q1.size();
            for(int i=0;i<size;i++){
                TreeNode* tmp = q1.front();
                q1.pop();
                if(tmp->left) q1.push(tmp->left);
                if(tmp->right) q1.push(tmp->right);
            }
            if(!q1.empty()) res.push_back(q1.back()->val);
        }
    }   
    vector<int> rightSideView(TreeNode* root) {
        if(!root) return res;
        q1.push(root);
        res.push_back(q1.back()->val);
        help();
        return res;
    }
};

108. Convert Sorted Array to Binary Search Tree
(给你一个升序的数组,将它转换为一个高度平衡的二叉查找树)

class Solution {
public:
    TreeNode* help(int left, int right, vector<int>& nums){
        if(left<=right){
            int mid = (left+right)/2;
            TreeNode* node = new TreeNode(nums[mid]);
            node->left = help(left,mid-1,nums);
            node->right = help(mid+1,right,nums);    
            return node;
        }else return nullptr;
    }
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        if(nums.size()==0) return nullptr;
        return help(0,nums.size()-1,nums);
    }
};

109. Convert Sorted List to Binary Search Tree
(给你一个排序好的链表,将它转换为一个高度平衡的二叉查找树)
(都是找中点,只不过,链表,用的是快慢指针来找中点)

class Solution {
public:
    ListNode* findCenter(ListNode* head, ListNode* tail)
    {
        if(head==tail || head->next==tail) return head;
        ListNode* slow = head;
        ListNode* fast = head->next->next;
        while(fast != tail)
        {
            slow = slow->next;
            fast = fast->next;
            if(fast != tail) fast = fast->next;
        }
        return slow;
    }
    TreeNode* helper(ListNode* head, ListNode*tail)
    {
        if(head == tail) return NULL;
        if(head->next == tail) return new TreeNode(head->val);
        ListNode* center = findCenter(head, tail);
        TreeNode* t1 = helper(head, center);
        TreeNode* t2 = helper(center->next, tail);
        TreeNode* tree = new TreeNode(center->val);
        tree->left = t1;
        tree->right = t2;
        return tree;
    }
    TreeNode* sortedListToBST(ListNode* head) 
    {
        return helper(head, NULL);
    }
};

95. Unique Binary Search Trees II
(给一个数字n,产生所有结构上唯一的二叉查找树,使得能够存储1到n的数)
(这个题要做一个动态规划,因为,当 n 相同的时候,能够产生的二叉查找树的数量也是固定的)

241. Different Ways to Add Parentheses
(给一个包含数字和操作符的字符串,返回所有通过数字和操作符所组合的可能的结果)

class Solution {
public:
    vector<int> diffWaysToCompute(string input) {
        if(input.size() ==0) return {};
        vector<int> result;
        for(int i = 0; i < input.size(); i++)
        {
            if(input[i]!='+' &&input[i]!= '-' &&input[i]!= '*') continue;
            auto vec1 = diffWaysToCompute(input.substr(0, i));
            auto vec2 = diffWaysToCompute(input.substr(i+1));
            for(auto val1: vec1)
            {
                for(auto val2: vec2)
                {
                    if(input[i]=='+') result.push_back(val1+ val2);
                    else if(input[i]=='-') result.push_back(val1 - val2);
                    else if(input[i]== '*') result.push_back(val1 * val2);
                }
            }
        }
        return result.empty()?vector<int>{stoi(input)}:result;
    }
};

6. ZigZag Conversion

clipboard1.png

// 这个题的解决方法是逐行逐行地进行计算,并找到对应的每一个数的规律。

class Solution {
public:
    string convert(string s, int numRows) {
        string res="";
        if(s=="") return res;
        if(numRows==1||s.size()<=numRows) return s;  // 单行和单列的时候都是返回原来原有的字符串。

        for(int i=0;i<numRows;i++){
            if(i==0||i==numRows-1){
                for(int j=i;j<s.size();){
                    res= res + s[j];
                    j=j+(numRows-1)*2; 
                }
            }else if(i!=numRows-1){
                for(int j=i;j<s.size();){
                    res= res + s[j];
                    j=j+(numRows-i-1)*2;
                    if(j<s.size()){
                        res= res + s[j];
                        j=j+i*2;
                    }
                }
            }
        }
        return res;
    }
};

119 Pascal's Triangle II
(给一个索引k,返回第k行的杨辉三角的数组)

class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int> result(rowIndex+1, 0);
        result[0]=1;
        for(int i=1; i<=rowIndex; i++) for(int j=i; j>=1; j--) result[j]=result[j]+result[j-1];
        return result;
    }
};

89. Gray Code
(格雷码是这么一组数,前后的两个数的的二进制位只相差1)
比如:n=2,return [0,1,3,2]

class Solution {
public:
    vector<int> grayCode(int n) {
        vector<int> res={0};
        for(int i=0;i<n;i++){
            int size = res.size();
            for(int j=size-1;j>=0;j--) res.push_back(res[j]+(1<<i));
        }
        return res;
    }
};

274. H-Index
For example, given citations = [3, 0, 6, 1, 5], which means the researcher has 5 papers in total and each of them had received 3, 0, 6, 1, 5 citations respectively. Since the researcher has 3 papers with at least 3 citations each and the remaining two with no more than 3 citations each, his h-index is 3.
(在一维数组中进行统计,可以看出很多关系出来,比如下面的方法,通过统计的方法,可以知道,比3大的数有多少个)
[3, 0, 6, 1, 5] -> [1,1,0,1,0,2] (对于下标为3的时候,可以得出有多少个数大于等于3)

class Solution {
public:
    int hIndex(vector<int>& citations) {
        int n = citations.size();
        if (n == 0) return 0;
        
        vector<int> hindex(n+1);
        
        for(int val: citations){
            if(val >= n) hindex[n]++;
            else hindex[val]++;
        }

        int sum = 0;
        int i = n;
        while (i > 0) {
            sum += hindex[i];
            if (i <= sum) return i;
            i--;
        }
        return 0;
    }
};

275. H-Index II
(What if the citations array is sorted in ascending order? Could you optimize your algorithm?)
(基本上,一谈到排序的数组,就想到用二分的方法,找到( size()-i) == nums[i]);

class Solution {
public:
    int hIndex(vector<int>& citations) {
        if(citations.size()==0) return 0;
        if(citations.size()==1) return 1<citations[0]?1:citations[0];
        else{
            int size = citations.size();
            int left = 0,right = citations.size()-1;
            while(left<right){
                int mid = left + (right-left)/2;
                if(citations[mid]==(size-mid)) return citations[mid];
                else if(citations[mid]>(size-mid)) right = mid;
                else left = mid+1;
            }
            return min(citations[left],(size-left));
        }
    }
};

289. Game of Life
(给一个 m*n 的矩阵,每一个单元格为 1 or 0 每一个单元格都会根据下面的四条规则被它的8个邻居所影响)
1、任何一个活着的单元格周围的8个单元格中活着的单元格小于2个,那么该单元格也会死掉。
2、任何一个活着的单元格周围有两个或者三个单元格活着,那么该单元格下一轮也会活着。
3、任何一个活着的单元格周围的8个单元格中有超过三个单元格或者,那么该单元格也会死掉
4、任何一个死掉的单元格周围的8个单元格中有刚好三个活着的邻居,则会变成活的单元格。
这种矩阵的变幻,又要求在原地变幻,其实就是说找到那些需要是活着的单元格就好:

void gameOfLife(vector<vector<int>>& board) {
    int m = board.size(), n = m ? board[0].size() : 0;
    for (int i=0; i<m; ++i) {
        for (int j=0; j<n; ++j) {
            int count = 0;
        // 将与自己在内的所有的数都统计一遍,然后只把需要将0变为1的case 选出来。
            for (int I=max(i-1, 0); I<min(i+2, m); ++I)
                for (int J=max(j-1, 0); J<min(j+2, n); ++J)
                    count += board[I][J] & 1;
            if (count == 3 || count - board[i][j] == 3)
                board[i][j] |= 2;
        }
    }
    for (int i=0; i<m; ++i)
        for (int j=0; j<n; ++j)
            board[i][j] >>= 1;
}

69、Sqrt(x)

class Solution {
public:
    int mySqrt(int x) {
        if(x==0) return 0;
        int left=1,right=x;
        while(left<=right){
            int mid = left+(right-left)/2;
            if(mid>x/mid) right=mid;
            else{
                if(mid+1>x/(mid+1)) return mid;
                left = mid+1;
            }
        }
        return left;
    }
};

332. Reconstruct Itinerary

class Solution {
public:
    vector<string> vec;
    stack<string> st;
    vector<string> findItinerary(vector<pair<string, string>> tickets) {
        unordered_map<string,multiset<string>> record;
        for(auto p: tickets){
            record[p.first].insert(p.second);
        }
        // -----begin from "JFK"-----------
        string str = "JFK";
        while(str!=""){
            st.push(str);
            if(!record[str].empty()){
                string str_ = *record[str].begin();
                record[str].erase(record[str].begin());  // 需要注意的是,这个erase 最好是删除迭代器,因为里面是multiset,可以有多个相同的值
                str = str_;
            }else str="";
        }
        str = st.top();
        while(str!=""){
            if(record[str].empty()){
                vec.push_back(str);
                st.pop();
            }else{
                st.push(*record[str].begin());
                record[str].erase(record[str].begin());
            }
            if(st.size()>0) str = st.top();
            else str = "";
        }
        reverse(vec.begin(),vec.end());
        return vec;
    }
};

313. Super Ugly Number(这道题算是比较难的题)
写一个函数去找到第n个 super ugly number
Super ugly numbers are positive numbers whose all prime factors are in the given prime list primes of size k. For example, [1, 2, 4, 7, 8, 13, 14, 16, 19, 26, 28, 32] is the sequence of the first 12 super ugly numbers given primes = [2, 7, 13, 19] of size 4.
Note:
(1) 1 is a super ugly number for any given primes.
(2) The given numbers in primes are in ascending order.
(3) 0 < k ≤ 100, 0 < n ≤ 106, 0 < primes[i] < 1000.

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

推荐阅读更多精彩内容