zoukankan      html  css  js  c++  java
  • Leetcode题解(十一)

    31、Next Permutation

    题目

    这道题目的意思是给定一个序列,找出其按照字典顺序的下一个顺序,如果给定顺序是字典中的最后一个顺序,其下一个顺序则为字典中的第一个顺序。比如:

    1,2,3,4,5-----注,后面的顺序去掉逗号

    12354

    12435

    12453

    12534

    12543

    13245

    通过上面的例子可以发现规律,在得到13245序列时,其实是从12543的右往左做比较,如果左边比右边数字大,继续往左比较,直到左边数字比右边小,比如12543中,2的右边都是递增的,直到2比5小,因此在543中从右往左找到第一个比2大的数3,交换2,3得到13542,然后将3之后的数字从小到大排序就是所得序列,代码如下:

     1 class Solution {
     2 public:
     3     void nextPermutation(vector<int>& nums) {
     4         const int size = nums.size();
     5         int temp,left,right;
     6         if(size <= 1)
     7             return;
     8 
     9         if(2 == size)
    10         {
    11             temp = nums[0];
    12             nums[0] = nums[1];
    13             nums[1] = temp;
    14             return;
    15         }
    16 
    17         int index = size-1-1;//从倒数第二个开始
    18 
    19         while (index>=0)
    20         {
    21             if(nums[index] >= nums[index + 1])//等号很重要,比如(5,1,1)的情况
    22                 index--;
    23             else
    24                 break;
    25         }
    26 
    27 
    28 
    29         if(index>=0)
    30         {
    31             right = size - 1;
    32             while(right > index)
    33             {
    34                 if(nums[right] <= nums[index])//等号很重要,比如(5,1,1)的情况
    35                     right--;
    36                 else
    37                     break;
    38             }
    39 
    40             if(right>index)
    41             {
    42                 temp = nums[right];
    43                 nums[right] = nums[index];
    44                 nums[index] = temp;
    45             }
    46             left = (++index);
    47         }
    48         else
    49             left = 0;
    50 
    51         right = size-1;
    52 
    53         while (left <= right)
    54         {
    55             temp = nums[right];
    56             nums[right] = nums[left];
    57             nums[left] = temp;
    58             left++;
    59             right--;
    60         }
    61 
    62     }
    63 };

     -----------------------------------------------------------------------------------------------------分割线-----------------------------------------------------------------------

    32、Longest Valid Parentheses

    题目

    这道题在具体实现的时候,大家第一反应肯定是要用到stack结构,因为在这种成对匹配的题型中,stack是首选的数据结构。仔细分析题目可得知,题目要求找出最长的合法括号对子串,这道题难点在于需要分析会出现的错误种类,经过分析总结,可以得出如下的错误种类:

    1、当遍历到字符串当前字符s[index] ==')'并且stack是空的,也就是说,字符串s从0到index-1的字符都能两两匹对,比如“()()())xxxxx”中,index=6时就是这种情况,针对这种情况,如果我事先已经知道了index之前的字符串中合法子串的最大长度,为max,那么从index+1又可看作是一个新的、从"0"开始处理的字符串s';并且问题规模比之前的s更小了;

    2、第二种错误种类不能从当前字符来判断,这种错误类型是这中模式s="--------(----(----",s中多出了两个左括号,其他部分都是刚好匹配的合法串;

    通过上面的描述,下面用比较正规的描述一下这几种错误:

    a、假设X是左右括号刚好匹配的字符串,比如"()()"、"(())"等,X可以是空串,s'是s的子串,s'也可以是空串;

    b、错误模式一:s = “X)s'”;

    c、错误模式二:s = “X(s'”;

    d、除了这两种类型,没有其他的错误类型了;

    有人会问s="X)(s'"是哪一种,其实这种错误时两种错误的结合,拆分为"X)"和"(s‘"即可;

    针对错误模式一,只需要保存好X的长度,然后从s’开始下一轮算法执行,而s'是比s规模更小的串;

    针对错误模式二,需要比较s'的最长合法子串和X的长度,然后进行比较,比如s="--------(----(----",我只需要在栈中保存好这两个多余的左括号的下标,然后从字符串的末尾开始,从栈中弹出栈顶下标(其实就是s中第二个多余字符的下标)index,end-index就是合法字符串的长度,及第二个左括号右边那部分的长度,接着end赋值为index-1,重复如此计算得到最后的结果;

    代码如下:

     1 class Solution {
     2 public:
     3     int longestValidParentheses(string s) {
     4         if(""==s)
     5             return 0;
     6         stack<int> myStack;
     7         int index = 0;
     8         int res=0;
     9         int start=0,end;
    10         int temp;
    11 
    12         while (s[index]!='')
    13         {
    14             if('(' == s[index])
    15             {
    16                 myStack.push(index);
    17             }
    18             else
    19             {
    20                 if(myStack.empty())//错误模式一
    21                 {
    22                     if(index - start > res)
    23                         res = index - start;
    24                     start = index+1;
    25                 }
    26                 else
    27                 {
    28                     myStack.pop();
    29                 }
    30             }
    31             index++;
    32         }
    33         end =index-1;
    34         if(myStack.empty())
    35         {
    36             if(end - start+1 > res )
    37                 res = end -start+1;
    38                 
    39             return res;
    40         }
    41         while(!myStack.empty())
    42         {
    43             temp = myStack.top();
    44             myStack.pop();
    45             if(end - temp > res)
    46                 res = end -temp;
    47 
    48             end = temp-1; 
    49         }
    50         
    51         if(end - start+1 > res)
    52             res = end -start+1;
    53         return res;
    54     }
    55 };
  • 相关阅读:
    git常用命令
    代码实现-栈、队列、双端队列
    websocket实现简单的单聊
    websocket实现简单的群聊
    成员
    反射
    类与类之间的关系
    常用模块-02
    模块
    微信小程序表单多页面步骤提交
  • 原文地址:https://www.cnblogs.com/LCCRNblog/p/5041639.html
Copyright © 2011-2022 走看看