字符串中的第一个唯一字符,给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。

题记:
给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。

示例 1:
输入: s = “leetcode”
输出: 0

示例 2:
输入: s = “loveleetcode”
输出: 2

示例 3:
输入: s = “aabb”
输出: -1

提示:
1 <= s.length <= 105
s 只包含小写字母

题目来源:
作者:LeetCode
链接:https://leetcode.cn/leetbook/read/top-interview-questions-easy/xn5z8r/
来源:力扣(LeetCode)

自己想出的方法:

一:利用集合处理

class Solution {

    /**
     * @param String $s
     * @return Integer
     */
    function firstUniqChar($s) {
        //先拆分为数组
        $s_arr = str_split($s);

        //过滤掉重复项
        $s_union_arr = array_unique($s_arr);

        //重复的键值对
        $repeat_arr = array_diff_key($s_arr,$s_union_arr);

        //对重复的键值对去重
        $no_repeat_arr = array_unique($repeat_arr);

        //去掉重复项后的唯一字符键值对
        $unionque_arr = array_diff($s_union_arr,$no_repeat_arr);
        if(empty($unionque_arr)){
            return -1;
        }

        //返回数组中当前单元的键名
        $key_current = key($unionque_arr); 
        return $key_current;

    }
}

$s = "loveleetcode";
$solution = new Solution();
$result = $solution->firstUniqChar($s);
print_r($result);
/**
输出结果为:2
*/

二:暴力双循环(效率最低)

class Solution {

    /**
     * @param String $s
     * @return Integer
     */
    function firstUniqChar($s) {
        //暴力循环(效率低),出现超时现象
        //先拆分为数组
        $s_arr = str_split($s);
        $length = count($s_arr);
        $map = [];  //重复元素数组初始化
        for($i = 0; $i < $length; $i++){
            for($j = $i + 1; $j < $length; $j++){
				if($s_arr[$i] == $s_arr[$j]){
					$map[$s_arr[$i]] = $s_arr[$i];
				}
            }
        }

        //原数组与重复元素数组取差集
        $unique_array = array_diff($s_arr,$map);
        if(!empty($unique_array)){
            return key($unique_array);
        }else{
            return -1;
        }

    }
}

$s = "loveleetcode";
$solution = new Solution();
$result = $solution->firstUniqChar($s);
print_r($result);
/**
输出结果为:2
*/

官方解题方法:

一:两次遍历
第一遍先统计每个字符出现的次数,第二遍再次从前往后遍历字符串s中的每个字符,如果某个字符出现一次直接返回,原来比较简单,看下代码

    public int firstUniqChar(String s) {
        int count[] = new int[26];
        char[] chars = s.toCharArray();
        //先统计每个字符出现的次数
        for (int i = 0; i < s.length(); i++)
            count[chars[i] - 'a']++;
        //然后在遍历字符串s中的字符,如果出现次数是1就直接返回
        for (int i = 0; i < s.length(); i++)
            if (count[chars[i] - 'a'] == 1)
                return i;
        return -1;
    }

转换为PHP代码为:

function firstUniqChar($s) {
 	//拆分为数组
    $s_arr = str_split($s);
    $str_count = [];
    //先统计各个字符出现的次数,字符为键,值为次数
    foreach($s_arr as $key => $value){
        if(!isset($str_count[$value])){
            $str_count[$value] = 1;
        }else{
            $str_count[$value]++;
        }
    }
	
	if(!empty($str_count)){
		//在数组中搜索给定的值(1),如果成功则返回首个相应的键名
	      	$key_char = array_search(1,$str_count);
		if($key_char){
			//再去原数组里搜索首次出现不重复的值,返回首个键名
			$value_char = array_search($key_char,$s_arr);
			return $value_char;
		}
		return -1;
	}
	return -1;
}

二:使用HashMap解决

    public int firstUniqChar(String s) {
        Map<Character, Integer> map = new HashMap();
        char[] chars = s.toCharArray();
        //先统计每个字符的数量
        for (char ch : chars) {
            map.put(ch, map.getOrDefault(ch, 0) + 1);
        }
        //然后在遍历字符串s中的字符,如果出现次数是1就直接返回
        for (int i = 0; i < s.length(); i++) {
            if (map.get(chars[i]) == 1) {
                return i;
            }
        }
        return -1;
    }

三:使用Java的api

一个从前查找,一个从后查找,如果下标相等,说明只出现了一次

    public int firstUniqChar(String s) {
        for (int i = 0; i < s.length(); i++)
            if (s.indexOf(s.charAt(i)) == s.lastIndexOf(s.charAt(i)))
                return i;
        return -1;
    }

官方推荐答案:

class Solution {


    /**
     * @param String $s
     * @return Integer
     */
    function firstUniqChar($s) {
	
        $char     = count_chars($s,1);	//count_chars — 返回字符串所用字符的信息
        $indexarr = [];
        foreach($char as $k => $v){		//k为字符字节值,v为次数
            if($v == 1){
                $chr   = chr($k);		//chr — 从数字生成单字节字符串
                $index = strpos($s,$chr);	//strpos() - 查找字符串首次出现的位置
                $indexarr[] = $index;
            }
        }
        if(count($indexarr) > 0) return min($indexarr);	//min — 找出最小值
        return -1;
    }
}


$s = "loveleetcode";
$solution = new Solution();
$result = $solution->firstUniqChar($s);
print_r($result);
/**
输出结果为:2
*/

官方解题来源:
作者:数据结构和算法
链接:https://leetcode.cn/leetbook/read/top-interview-questions-easy/xn5z8r/?discussion=6TyKA7
来源:力扣(LeetCode)

其他方法(PHP):

function firstUniqChar($s) {
	$chr = null;
	for($i = 0; $i < strlen($s); $i++){
	    //substr_count — 计算字串出现的次数
        //substr — 返回字符串的子串
		if(substr_count($s, substr($s, $i, 1)) == 1){
			return $i;
			//return substr($s, $i, 1);
		}
	}
	return -1;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值