一道面试编程题:找出一个字符串中:同一字符相隔最长距离的那个字符

计题目解释:

"abscdas" 这个字符串两个 a 字符距离最远(距离是5),而 s 字符只是距离4.

  • 也就是说拥有距离的字符至少需要出现两次

"absdakueba" 这个字符a出现三次,算最远的那两个a的距离,所以这个还是返回a字符。

思路

  1. 首先创建一个 maxChar存储当前拥有最长距离的字符,maxLen存储对应的长度。
  2. 遍历字符串,用HashSet存第一次出现的字符,当出现冲突时,说明有字符重复出现,计算距离需要获得两个值:
  • 第一个值:该字符第一次出现的位置 j (需要找个结构存储它,这时我当时纠结的地方),想了两个方法:
  1. 第一个暴力的,直接 indexOf(当前字符)-》返回第一次出现的位置。这个每次都搜索,很花费时间。
  2. 于是,想到第二种,建一个数组int[256](所有字符也就256个,Ascii),出现了就存个值。O(1)的复杂度。
  • 第二个值:当前出现的位置 i(这个直接就可以获得)
  1. 用 i - j 得出这个重复出现的字符这次的的间隔长度curMaxLen 。这个curMaxLen与maxLen比较,如果新的更长,那么替换长度,并且maxChar也换成当前的字符。

上代码

//输入是 String;输出 char

import java.util.HashSet;

public class FindLongestDistanceCharPairs {
    public static char findLongestCharPairs(String str){
        if (str.length() <= 1) {
            return ' ';
        }
        int maxLen = 0;
        char maxChar = ' ';
        //存储当前出现过的数组,用来去重
        HashSet hashSet = new HashSet();

        //记录字符第一次出现的索引,直接建立一个全部字符数目大小的数组,总共也就256个。
        int[] firstIndex = new int[256];

        for(int i = 0;i < str.length();i++){
            if(hashSet.add(str.charAt(i))){
                //记录当前i对应字符第一次出现的位置
                firstIndex[str.charAt(i)] = i;
            }else{
                //插入没成功,说明有冲突,再次出现-》计算同样两个字符间隔长度
                //该冲突字符第一次出现的位置 j
                int j = firstIndex[str.charAt(i)];
                int curMaxLen = i - j;

                if (maxLen < curMaxLen) {
                    maxLen = curMaxLen;
                    maxChar = str.charAt(i);
                }
            }
        }
        System.out.println(maxLen);
        return maxChar;

    }

    public static void main(String[] args) {
        String str = "abbacdisauhfiugiugcouiqwgdcpiqpiubqiuncidsaunbibvasidbcaqpoavj'qk[408507-25!@%#^%*%&(^()&+{{}}:LKKPHJOGOIUOPYHGIPb";
        System.out.println(findLongestCharPairs(str));
    }
}

复制代码
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值