• SRM DIV2 579 UndoHistory


    算法过程:

    1.每个字符串的输出,需要经历的步骤是:

      a.检查undo list 更新 buff;

      b.填写buff,并更新undo list;

      c.回车;

    2.关键是步骤a,既要考虑从undo list中选出来的前缀A,也要考虑buff中现有的B;

    3.通常情况,直接用A替换B。特殊情况:

      1) B和A相同,则不需要替换;

      2) B是A的前缀,并且B.length+2>A.length,不需要替换。

    4.时间复杂度:O(n^2)

    菜鸟的代码:

    import java.util.*;
    import java.util.regex.*;
    import java.text.*;
    import java.math.*;
    
    
    public class UndoHistory
    {
        public int minPresses(String[] lines)
        {
            List<String> undo = new ArrayList();
            int i,j,k,max,count;
            String temp,m,buff;
            
            buff = "";
            undo.add("");
            count = 0;
            for(i=0;i<lines.length;i++){
                //find the longest substr in undo
                Iterator<String> it = undo.iterator();
                m="";
                while(it.hasNext()){
                    temp = it.next();
                    if(temp.length()>m.length()&&temp.length()<=lines[i].length()){
                        if(temp.equals(lines[i].substring(0,temp.length()))){
                            m = temp;
                        }
                    }
                }
                            
                //update the buff
                //System.out.println("buff="+buff+"m="+m+"count="+count);
                if(!m.equals(buff)){
                    //count the mouse click
                    if(buff.length()<=lines[i].length()&&buff.equals(lines[i].substring(0,buff.length()))&&m.length()<=buff.length()+2){
                        //这个情况很特殊,很容易漏掉
                    }
                    else{
                        count+=2;
                        buff=new String(m);
                    }
                }
                //System.out.println("char:"+count);
                //if the longset undo equals buffer,then no mouse clicks
            j=buff.length();
                for(;j<lines[i].length();j++){
                    buff+=lines[i].charAt(j);
                    undo.add(new String(buff));
                    //count the char
                    count++;
                }
                //System.out.println("enter:"+count);
                //count the enter
                count++;
            }
            return count;
        }
        
    
    }
    //Powered by KawigiEdit 2.1.4 (beta) modified by pivanof!

    大神的代码java:

    import java.util.*;
    import java.util.regex.*;
    import java.text.*;
    import java.math.*;
     
     
    public class UndoHistory
    {
      public int minPresses(String[] lines)
      {
        HashSet<String> prefixes = new HashSet<String>();
        int ans = 0;
        String prev = "";
        for (String s : lines) {
          int cur = s.length() + 3;
          if (s.startsWith(prev)) {
            cur = s.length() - prev.length() + 1;
          }
          for (int i = 1; i <= s.length(); ++i) {
            if (prefixes.contains(s.substring(0, i))) {
              cur = Math.min(cur, s.length() - i + 3);
            }
            prefixes.add(s.substring(0, i));
          }
          prev = s;
          ans += cur;
        }
        return ans;
      }
      
     
    }

    大神的代码c++:

    #include <vector>
    #include <list>
    #include <map>
    #include <set>
    #include <deque>
    #include <stack>
    #include <algorithm>
    #include <functional>
    #include <numeric>
    #include <utility>
    #include <iostream>
    #include <iomanip>
    #include <cstdio>
    #include <cmath>
    #include <cstdlib>
    #include <ctime>
    #include <string>
    #include <cstring>
     
    using namespace std;
     
    class UndoHistory {
    public:
      int minPresses(vector <string>);
    };
     
    int UndoHistory::minPresses(vector <string> lines) {
      
      int c=lines[0].length()+1;
      int len,max,ind,last=0;
      
      int x=lines.size();
      int ar[x];
      
      for (int i=0;i<x;i++)
      {
        ar[i]=lines[i].length();
      }
      
      for (int i=1;i<x;i++)
      {
        max=-1,ind=-1;
        for (int j=i-1;j>=0;j--)
        {
          len=0;
          for (int k=0;k<min(ar[j],ar[i]);k++)
          {
            if (lines[j][k]!=lines[i][k])
              break;
            else
              len++;
          }
          if (j == i-1)
            last=len;
          if (len > max)
          {
            max=len;
            ind=j;
          }
        }
        
        if (ind == i-1 && max==ar[i-1])
          ;
        else if (max == last+1 && last==ar[i-1])
        {
          max--;
        }
        else
          c+=2;
        if (max > 0)
        {
          len=ar[i] - max;
        }
        else
        {
          len=ar[i];
        }
        c+=len+1;
      }
      return c;
        
    }
     
     
    //Powered by [KawigiEdit] 2.0!

     分析:

      算法:Greedy, Simple Search, Iteration

      对比:

        1.Java大神的思考方式比我牛。

          我是先到undo list里把前缀找出来,然后再拿前缀和buff当前值做比较,决定要不要替换。

          大神用优化的思维来看待这个问题,首先考虑只采用buff的情况,然后再遍历undo list,看通过history能不能有优化。

        2.Java大神的HashSet用得帅气,学习了。

        3.C++大神的代码可读性捉急。。。

        4.C++大神的想法和我的比较接近。但是他没有真实地用一个undo list。而是每次都那当前字符串和以前的字符串求一个最长前缀。这样做的确可以节省不少存储空间,但是略显麻烦。。。

      总结:

        1.java大神的代码的确体现出了greedy算法思想。少去了很多细节上的判断处理。

        2.菜鸟表示要好好去学习一下HashSet。

  • 相关阅读:
    Windows如何快速远程到另一台Windows并管理多个远程服务器
    基于视觉反馈的步进电机X-Y平台控制
    相机位姿估计3:根据两幅图像的位姿估计结果求某点的世界坐标
    相机位姿估计2:[应用]实时位姿估计与三维重建相机姿态
    相机位姿估计1_1:OpenCV:solvePnP二次封装与性能测试
    求空间内两条直线的最近距离以及最近点的坐标(C++)
    相机位姿估计1:根据四个特征点估计相机姿态
    相机位姿估计0:基本原理之如何解PNP问题
    记2016年中国移动广西公司面试(计算机类)
    子坐标系C在父坐标系W中的旋转问题
  • 原文地址:https://www.cnblogs.com/wang3/p/3163928.html
Copyright © 2020-2023  润新知