海贼007

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

算法过程:

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。

posted on 2013-07-04 10:45  wzhscript  阅读(185)  评论(0编辑  收藏  举报