力扣(字符串):942、344、557、806、1047

一、942

 

思路:

我们首先考虑字符串中的第一个字母。如果 S[0] == 'I',那么我们只要令 A[0] = 0,就一定能满足 A[0] < A[1]。如果 S[0]== 'D',同样我们只要令 A[0] = N,就一定能满足 A[0] > A[1]。

接下来,当我们考虑 S 中剩下的 N - 1 个字母时,还剩下 N 个数可以使用,这 N 个数为 [0 .. N - 1] 或 [1 .. N]。可以发现,由于 S[0] 的值已经确定,那么剩下 S 中的 N - 1 个字母和 N 个可用的数变成了一个和原问题相同,但规模为 N - 1 的问题。即如果 S[1] == 'I',我们就令 A[1] 为剩下数中最小的那个数;如果 S[1] == 'D',我们就令 A[1] 为剩下数中最大的那个数。

我们每次会把可以使用的数的集合中的最小值或最大值取出,并放到当前的位置,因此可以使用的数的集合总是连续的,就可以非常方便的进行维护。

算法:

我们维护当前未使用的最小和最大的数,它们对应的区间为当前未使用的数的集合。从左向右扫描字符串,如果碰到 'I',就取出当前最小的数,否则取出当前最大的数。

代码:

class Solution {
public:
    vector<int> diStringMatch(string S) {
        int p=0;
        int q=S.length();
        vector<int> res;
        
        for(int i=0;i<S.length();i++)
        {
            if(S[i] =='I')
            {
                res.push_back(p++);
            }
            else if(S[i] =='D')
            {
                res.push_back(q--);
            }
        }
        
        res.push_back(q);
        return res;
    }
};

 

二、344

思路:

1:用双指针,同时从头部和尾部开始进行交换2个指针的值
2:并自增自减的向中间遍历
3:直到触发基准条件:2个指针开始中间重合 返回即可

代码:

class Solution {
public:
    void reverseString(vector<char>& s) {
        for(int i=0; i<(s.size()/2); i++)
        {
            char tmp=s[s.size()-1-i];
            s[s.size()-1-i] = s[i];
            s[i]=tmp;
        }
    }
};

三、557

 

思路:

用i一直遍历这个字符串,然后用j,k标记首尾,每个被空格隔开的子串的并交换;

代码:

class Solution {
public:
    string reverseWords(string s) {
        
        int i = 0;
        int j = 0;
        while (i < s.size() )
        {
            while (i < s.size() && s[i] != ' ')
                ++i;
            int k = i;
            while (j < k)
            {
                swap(s[j++], s[--k]);
            }
            j = ++i;
        }
        return s;
    }
};

四、806

 

思路:

定义一个记录当前行长度(从0开始)、和要写进去的当前字母的长度、如果当前行长度加上要写进去的长度大于100,说明写不下,则行数加一,把当前行的值更新为要写的长度,一直循环。

代码:

class Solution {
public:
    vector<int> numberOfLines(vector<int>& widths, string S) {
        
        vector<int> res={1,0};
        
        int rowlen=0;   //当前行
        for(int i=0;i<S.size();i++)
        {
            int cur=widths[S[i] - 'a'];
            
            if((rowlen+cur)>100)
            {
                res[0]++;
                rowlen=cur;
            }
            else
            {
                rowlen+=cur;
            }
        }
        res[1]=rowlen;
        return res;
    }
};

五、1047

思路:压栈和栈顶元素相同,栈顶远胜于弹出、出栈保存再反转

代码:

 class Solution {
public:
    string removeDuplicates(string S) 
    {
        stack<char> stk;
        
        for(int i=0;i<S.size();i++)     //压入数据
        {
            if(stk.empty())
            {
                stk.push(S[i]);
            }
            else
            {
                if(S[i]==stk.top())   //相等弹出栈顶元素
                {
                    stk.pop();
                }
                else
                    stk.push(S[i]);
            }
        }
        
       string res;
        
       while(!stk.empty())
       {
           res.append(1,stk.top());
           stk.pop();
       }
        
        reverse(res.begin(),res.end());  //反转函数
        return res;
        
    }
};

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值