leetcode刷题_day2

763.Partition Labels

  1. 本题根据问题描述,一定要找到一种方式记录下每个字母最后出现的位置。
    使用for循环利用字符常量做减法存储26个英文字母最后出现在string中的位置是本题中学到的一点
int Last_pos[26];
for(int i=0;i<s.length();i++)
    Last_pos[s[i]-'a']=i;

这样Last_pos数组中存储的是就是26个字母最后出现的下标

  1. 如何切割?
    设置一个标志位start=0和end=0。从左到右依次遍历,对于访问到的每个字母,得到该字母最后一次出现的下标位置。其实这时已经得到了一个片段,我们可以进行切割的判断是该片段里所有字母的最后一次出现的下标不会小于当前字母出现的下标。用max()函数进行比较对于初学者还是难想到的。
    换句话说,对于每个访问到的字母C,得到当前字母最后一次出现的下标位置 e n d c end_{c} endc,则当前片段的结束下标一定不会小于 e n d c end_{c} endc,因此令 e n d = m a x ( e n d , e n d c ) end = max(end,end_{c}) end=max(end,endc)

  2. 附leetcode官方题解(此题理解容易但实现起来还是容易走很多弯路)

class Solution {
    public List<Integer> partitionLabels(String s) {
        int[] last = new int[26];
        int length = s.length();
        for (int i = 0; i < length; i++) {
            last[s.charAt(i) - 'a'] = i;
        }
        List<Integer> partition = new ArrayList<Integer>();
        int start = 0, end = 0;
        for (int i = 0; i < length; i++) {
            end = Math.max(end, last[s.charAt(i) - 'a']);
            if (i == end) {
                partition.add(end - start + 1);
                start = end + 1;
            }
        }
        return partition;
    }
}

122. Best Time to Buy and Sell Stock II

  1. 这道题比较简单,但是需要思路转换的一点是,一般来说股票的买卖是有个范围的,所以如果想找一个一直赚钱的区间,最后把赚到的钱加一起,讨论起来情况会很多,尤其是区间的开始和结尾需要分类讨论。如果转换为每次买卖都是一天就会简单一点。因为题中要求可以一天买卖,所以都化为单位为1的小区间,然后找增益为正的就行。

  2. 附上代码题解(空间复杂度比较大)

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int length = prices.size() - 1;
        vector<int> gain(length);
        for (int i = 0; i < length; ++i)
            gain[i] = prices[i + 1] - prices[i];
        int start = 0, end = 0, profit = 0;
        for (int i = 0; i < length; ++i)
        {
            if (gain[i] >= 0)
            {
                profit = profit + gain[i];
            }
        }
        return profit;
    }
};

406.Queue Reconstruction by Height

  1. 由于笔者在刷这道题时没有看过排序算法相关的内容,所以有点迷,不知道如何下手。所以参考了题解的解法,不过官方题解写的非常绕,看的云里雾里,这里简述了一个精选参考答案。
  2. 套路:一般这种数对,还涉及到排序的,根据第一个元素正向排序,根据第二个元素反向排序,或者根据第一个元素反向排序,根据第二个元素正向排序,往往会有奇效。换句话说,假如先按第一个元素在正向排序,如果遇到数值相同的,则按第二个元素反向排序

先说明C++如何对一个vector数对实现如上所示的排序。

vector<vector<int> > people;
sort(people.begin,people.end(),[](const vector<int> & u,const vector<int> & v){
   return u[0]>v[0] || (u[0]==v[0] && u[1]<v[1]) ;
})
  1. 按照如上顺序排好之后,从左到右依次遍历,设遍历到的位置下标为i,i代表真实情况下该序列正好有i个身高大于或等于hi的人。如果此时的数对中hi的值大于或等于i,则将该数对插入到新数对后面,如果此时数对中的hi值小于i,则将该数对插入到新数对hi位置处。
    附C++实现代码:
class Solution {
public:
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort(people.begin(),people.end(),[](const vector<int> & u,const vector<int> & v){
            return u[0]>v[0] || (u[0]==v[0] && u[1]<v[1]);
        });
        int length =people.size();
        vector<vector<int> > ans;
        for(int i=0;i<length;++i)
        {
            if(people[i][1]>=i)
                ans.push_back(people[i]);
            else
                ans.insert(ans.begin()+people[i][1],people[i]);
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值