牛客网 Rabbit的字符串

题目描述

Rabbit得到了一个字符串,她的好朋友xxx可以给这个字符串施加一次魔法。
魔法可以选择字符串的任一位置,并将该位置后面的所有字符水平拼接到串首。
例如:对于字符串abcde,可以通过施加魔法得到cdeab。
如果xxx通过施加魔法将字符串的字典序变得严格比之前的小,那么他将拿走这一字符串。
Rabbit想知道自己的字符串会不会被xxx拿走。

输入描述:
第一行一个整数n,表示字符串的长度。
接下来一行一个长度为n的只由小写字母组成的字符串。
输出描述:
如果Rabbit的字符串会被xxx拿走,输出“YES”。
否则输出“NO”。
(不输出引号)
示例1
输入

5
cdeab

输出

YES

说明

xxx可以把e之后的部分“ab”放到串首,得到abcde,字典序比cdeab小,故将拿走字符串。

示例2
输入

5
abcde

输出

NO

注:
1≤n≤100000

思路

将字符串拆成两部分后拼接成新的字符串再和原来字符串比较字典序即可。一点优化:先找到字符串中字典序最小的字母,然后仅用以这个字母作为开头拼接方式和原字符串比较即可。

java代码

import java.util.*;
public class Main{

    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String S=sc.next();
        char min=get_min(S,'z');
        for(int i=0;i<n;i++)
        {
            if(S.charAt(i)<=min)
            {
                  String pre=S.substring(i);
                  String post=S.substring(0,i);
                  String SS=pre+post;
                  if(SS.compareTo(S)<0)
                  {
                  System.out.println("YES");
                  return;
                  } 
            }
         }
             System.out.println("NO");
     }
    
    
           //找字符串中字典序最小的字母
            public static char get_min(String S,char m){
                  int n=S.length();
                  m=S.charAt(0);
                  for(int i=0;i<n;i++)
                  {
                     if(S.charAt(i)<=m) m=S.charAt(i);
                     if(m=='a') return m;
                  }
                    return m;
              }
        
    }

神奇脑回路

一开始看到这个题就想用字典树做,结果做了很多优化还是有两组数据没过(执行错误)。不知道可不可以优化了。先po个代码吧。有时间再看看问题出在哪。

java代码

import java.util.*;
import java.lang.Object;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String S=sc.next();
        Trie trie=new Trie();
        trie.root.equal=true;
        char min=get_min(S,'z');
        trie.Insert(S,S);
        Set<String> set=new HashSet<String>();
        for(int i=0;i<n;i++){
            if(S.charAt(i)<=min)
            {   
                String pre=S.substring(i);
                String post=S.substring(0,i);
                String SS=pre+post;
                if(set.contains(SS)) continue;
                else set.add(SS);
                if(trie.Insert(SS,S))
               {
                     System.out.println("YES");
                     return;
               }
            }
            
        }
             System.out.println("NO");
    }
    
    public static char get_min(String S,char m){
        int n=S.length();
        m=S.charAt(0);
        for(int i=0;i<n;i++){
            if(S.charAt(i)<=m) m=S.charAt(i);
            if(m=='a') return m;
        }
        return m;
    }
 
}

class TrieNode{
    public boolean equal;
    public TrieNode []next=null;
    public TrieNode(){
        equal=false;
        next=new TrieNode[26];
    }
}

class Trie{
    public  TrieNode root;
    public Trie(){
        root=new TrieNode();
    }
    
    public boolean Insert(String SS , String S){
        int len=SS.length();
        TrieNode p=root;
        for(int i=0;i<len;i++){
            int Ch=SS.charAt(i)-'a';
            int ch=S.charAt(i)-'a';
            if(p.equal&&Ch>ch) return false;
            if(p.equal&&Ch<ch) return true;
            if(p.next[Ch]==null){
                p.next[Ch]=new TrieNode();
                if(SS.charAt(i)==S.charAt(i))
                    p.next[Ch].equal=true;
            }
            p=p.next[Ch];
        }
         return false;
    } 
    
}

报错内容:

执行出错
请检查是否存在数组越界等非法访问情况
Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)
at java.lang.StringBuilder.append(StringBuilder.java:136)
at Main.main(Main.java:18)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值