剑指offer-第一个只出现一次的字符

题目描述
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).

思路
1.设置一个52大小的数组来存储字符
空间复杂度是O(1),时间复杂度是O(n)

public class Solution {
    public int FirstNotRepeatingChar(String str) {
        if(str.length() < 1){
            return -1;
        }
        int[] arr = new int[52];
        for(int i = 0;i < str.length();i++){
            char c = str.charAt(i);
            if(c >= 'a' && c <= 'z'){
                if(arr[c-'a'] == 0)
                    arr[c-'a'] = i+1;
                else
                    arr[c-'a'] = -1;
            }else{
                int index = c - 'A' + 26;
                if(arr[index] == 0)
                    arr[index] = i+1;
                else
                    arr[index] = -1;
            }
        }
        return search(arr);
    }
    public int search(int[] arr){
        int min = Integer.MAX_VALUE;
        for(int i = 0;i < 52;i++){
            if(arr[i] == -1 || arr[i] == 0){
                continue;
            }else{
                min = min > arr[i] - 1? arr[i]-1:min;
            }
        }
        return min;
    }
}

2.看剑指offer上的思路,使用HashMap
但是空间复杂度是O(n),不推荐,第一种方法是较好的

import java.util.HashMap;
public class Solution {
    public int FirstNotRepeatingChar(String str) {
        if(str.length() < 1){
            return -1;
        }
        HashMap<Character,Integer> hm = new HashMap<>();
        for(int i = 0;i < str.length();i++){
            char c = str.charAt(i);
            if(hm.containsKey(c)){
                int count = hm.get(c);
                hm.put(c,++count);
            }else{
                hm.put(c,1);
            }
        }
        for(int i = 0;i < str.length();i++){
            char c = str.charAt(i);
            if(hm.get(c) == 1){
                return i;
            }
        }
        return -1;
    }
}

3.CYC写的开了256的数组,原因是总共有256个ASCLL字符

public int FirstNotRepeatingChar(String str) {
    int[] cnts = new int[256];
    for (int i = 0; i < str.length(); i++)
        cnts[str.charAt(i)]++;
    for (int i = 0; i < str.length(); i++)
        if (cnts[str.charAt(i)] == 1)
            return i;
    return -1;
}

4、举一反三
相关题目:
(1)定义一个函数,从第一个字符串中删除在第二个字符串中出现过的所有字符
思路:可以创建一个用数组实现的简单哈希表,存储第二个字符串
遍历第一个字符串,如果字符串1中的字符出现在第二个字符串中,就删除它
(2)定义一个函数,删除字符串中所有出现的重复字符
思路:创建一个用数组实现的简单哈希表,遍历字符串,如果之前出现过,直接删除就行了
(3)在英语中,如果两个单词中出现的字母相同,并且两个字母出现的次数也相同,那么这两个单词互为变位词。
请完成一个函数,判断输入的两个字符串是不是互为变位词
思路:就是用数组实现一个简单的哈希表,遍历第一个字符串,用数组统计字符串中每个字符出现的次数,然后遍历第二个字符串,对应的数组中字符的次数减一,如果数组中的所有的次数都是0,那么这两个字符串就互为变位词。
我原来以为要使用两个数组,但是这样加一减一的操作,就会减少了一个数组空间的使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值