简单算法题整理

  • 一,初次尝试
    • 1.两数之和
    • 2.两数相加
    • 3.整数反转
    • 4.回文数
    • 5.罗马数字转十进制整数
    • 6.无重复字符的最长字串
    • 7.最长公共前缀
    • 8.有效的括号
    • 9.合并两个链表
  • 二、数组
    • 1、删除排序数组中的重复项
    • 2.买卖股票的最佳时机
    • 3.旋转数组
    • 4.存在重复
    • 5.只出现一次的数字
    • 6.两个数组的交集
    • 7.加一
    • 8.移动零
    • 9.两数之和
    • 10.有效的数独
  • 三、字符串
    • 1.反转字符串
    • 2.字符串中的第一个唯一字符
    • 3.有效的字母异位词

一,初次尝试

1.两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

我的编程:
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] result = new int[2];
        for(int i=0;i<nums.length;i++){
            for(int j=nums.length-1;j>i;j--){
                if(nums[j]+nums[i]==target){
                	result[0] = i;
                    result[1] = j;
                   return result;
            	}
            }
        }
        return null;
    }
}
10ms范例:
class Solution {
    public int[] twoSum(int[] nums, int target) {
        HashMap<Integer,Integer> s = new HashMap(nums.length);       
        int i;
        Integer temp;
        for (i=0;i<nums.length;++i)
            s.put(nums[i],i);    
        //有逻辑bug
        for (i=0;i<nums.length;++i)
        {
            temp = s.get(target-nums[i]);
            if (temp!=null && temp!=i)
                return new int[]{i,temp};
        }       
        return new int[]{0,0};
    }
}
2.两数相加

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

失败

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * } 我现在了解了这个集合,一个成员变量,一个自对象,一个构造函数。但是他是如何存储多位的?
 arrayslist linkedlist hashmap ,,如果是通过下表遍历首选arraylist 如果是通过首位末尾操作,首选linkedlist 而hashmap对于键值对的查询较为便利。
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        
    }
}
3.整数反转

给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

class Solution {
    /**
    如何处理符号问题,如何处理溢出问题,如何处理数据转换问题
    */
    public int reverse(int x) {
        String s = Integer.valueOf(x).toString();
        String k = "";
        String t = "-";
        if(s.startsWith(t)){
            k="-";
            s = s.substring(1);
        }
        for(int i=s.length()-1;i>=0;i--){
            if(s.charAt(i)==0) continue;
            k += s.charAt(i);
        }
        long l = Long.parseLong(k);
        int b ;
        if(l>Integer.MAX_VALUE||l<Integer.MIN_VALUE){
            b = 0;
        }else{
           b = Integer.parseInt(k);
        }
        return b;
    }
}
另一种思路
    public int reverse(int x) {
        int rev = 0;
        while (x != 0) {
            int pop = x % 10;
            x /= 10;
            if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
            if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
            rev = rev * 10 + pop;
        }
        return rev;
    }
特别的判断方法
class Solution {
    public int reverse(int x) {
        int ret = 0;
        while(x != 0) {
            int temp = ret*10 + x%10;
            if(temp / 10 != ret)
                return 0;
            ret = temp;
            x /= 10;
        }
        return ret;
    }
}
4.回文数
class Solution {
    public boolean isPalindrome(int x) {
        int[] a = new int[12];
        int i = 0;
        if(x <0){
            return false;
        }
        do{
            a[i] = x%10;
            x = x/10;
    		i++;
        }while(x!=0);
        for(int j=0,k=i-1;j<i/2;j++,k--){
            if(a[j]!=a[k]){
                return false;
            }
        }
        return true;
    }
}
5.罗马数字转十进制整数
class Solution {
    public int romanToInt(String s) {
        s=s+' ';
        int x = 0;
/*一般情况:
字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000
特殊情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900
*/
        for(int i=0;i<s.length();i++){
            if(s.charAt(i)=='M'){
                x=x+1000;
            }else if(s.charAt(i)=='D'){
                x=x+500;
            }else if(s.charAt(i)=='C'&&s.charAt(i+1)=='M'){
                x=x+900;
                i++;
            }else if(s.charAt(i)=='C'&&s.charAt(i+1)=='D'){
                x=x+400;
                i++;
            }else if(s.charAt(i)=='C'){
                x=x+100;
            }else if(s.charAt(i)=='L'){
                x=x+50;
            }else if(s.charAt(i)=='X'&&s.charAt(i+1)=='C'){
                x=x+90;
                i++;
            }else if(s.charAt(i)=='X'&&s.charAt(i+1)=='L'){
                x=x+40;
                i++;
            }else if(s.charAt(i)=='X'){
                x=x+10;
            }else if(s.charAt(i)=='V'){
                x=x+5;
            }else if(s.charAt(i)=='I'&&s.charAt(i+1)=='X'){
                x=x+9;
                i++;
            }else if(s.charAt(i)=='I'&&s.charAt(i+1)=='V'){
                x=x+4;
                i++;
            }else if(s.charAt(i)=='I'){
                x++;
            }else if(s.charAt(i)==' '){
                break;
            }else {
                return -1;
            }
        }
        return x;
    }
}
/*集合方式*/
class Solution {
    public int romanToInt(String s) {
       int result = 0;
		Map<Character, Integer> map = getMapRoman();
		char[] sArray = s.toCharArray();
		int i=0, j=1;
		for(;i<sArray.length-1;i++, j++){
			if(map.get(sArray[i]) >= map.get(sArray[j])){
				result += map.get(sArray[i]);
			}else{
				result -= map.get(sArray[i]);
			}
		}
		result += map.get(sArray[i]);
		return result;
    }
    public static Map<Character, Integer> getMapRoman() {
		Map<Character, Integer> map = new HashMap<>();
		map.put('I', 1);
		map.put('V', 5);
		map.put('X', 10);
		map.put('L', 50);
		map.put('C', 100);
		map.put('D', 500);
		map.put('M', 1000);
		return map;
	}
}
6.无重复字符的最长字串
/*为解决测试用例超时问题*/
class Solution {
    public int lengthOfLongestSubstring(String s) {
      	HashMap<Integer,String> map = new HashMap<>();
        String t;
        for(int i=0;i<s.length();i++){
            for(int j=s.length();j>i;j--){
                t = s.substring(i,j);
                if(unRepetition(t)){
                    map.put(t.length(),t);
                }
            }
        }
        return map.size();
    }
    public boolean unRepetition(String s){
        for(int i=0;i<s.length();i++){
            for(int j=i+1;j<s.length();j++){
                if(s.charAt(i)==s.charAt(j)){
                    return false;
                }
            }
        }
        return true;
    }
}
/*成功用例*/
class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s == null || s.length() == 0) {
            return 0;
        }
        int max = 0;
        Set<Character> set = new HashSet<>();
        int i = 0, j = 0;
        while(i<s.length()&&j<s.length()) {
            if(!set.contains(s.charAt(j))) {
                set.add(s.charAt(j++));
                max = Math.max(j-i,max);
            }else {
                set.remove(s.charAt(i++));
            }
        }
        return max;
    }
}
//第二种
class Solution {
    public int lengthOfLongestSubstring(String s) {
        char[] chas=s.toCharArray();
        int max=0;
        int[] n=new int[128];
        for(int i=0,j=0;j<chas.length;j++){
            i=Math.max(n[chas[j]],i);
            max=Math.max(max,j-i+1);
            n[chas[j]]=j+1;
        }
        return max;
    }
}
//我使用的方法的变种
class Solution {
    
    public int lengthOfLongestSubstring(String s) {
        int len = s.length();
        int childLen = 0;
        Map<Character, Integer> map = new HashMap<>();
        for (int i = 0, j = 0; j < len; j++) {
            if (map.containsKey(s.charAt(j))) {
                i = Math.max(map.get(s.charAt(j)), i);
            }
            childLen = Math.max(childLen, j - i + 1);
            map.put(s.charAt(j), j + 1);
        }
        return childLen;
    }
}
7.最长公共前缀
/*编写一个函数来查找字符串数组中的最长公共前缀;
如果不存在公共前缀,返回空字符串 "";所有输入只包含小写字母 a-z 。*/
class Solution {
    public String longestCommonPrefix(String[] strs) {
        String s=strs[0];
        String t="";
        for(int i=1;i<strs.length;i++){
            int j=0;
            while(j<Math.min(s.length(),strs[i].length())){
                if(strs[i-1].charAt(j)==strs[i].charAt(j)){
                    t=t+strs[i].charAt(j);
                }else{
                    break;
                }
                j++;
            }
            s=s.length()>t.length()?t:s;
            t="";
            if(s.equals("")){
                return "";
            }
        }
        return s;
    }
}
/*截断字符法*/
class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs==null||strs.length==0)
            return "";
        for(int i=0;i<strs[0].length();i++){
            char c=strs[0].charAt(i);
            for(int j=0;j<strs.length;j++)
                if(i==strs[j].length()||strs[j].charAt(i)!=c)
                    return strs[0].substring(0,i);
        }
        return strs[0];
  
8.有效的括号
/**给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

分析:字符串长度一定是偶数;左右括号的个数必须相同;括号的顺序有一定的要求;不同括号交叉会有出错的风险
偶数好办,个数相同就采用计数方式;括号的顺序有要求---就采用左加右减的操作--判断数为非负数;括号之间交叉:
	将有效的括号进行删除,如果括号之间有非法交叉,那么就会导致整体括号对不再完整,返回false

收获:我所考虑的顺序问题,其实归根结底就是下一个右括号和上一个左括号的类型不匹配,计算机不会直观的顺序阅读,他们只考虑匹配。

java提供的堆栈
*/
class Solution {
    private HashMap<Character,Character> mappings;
    public Solution() {
        this.mappings = new HashMap<Character, Character>();
        this.mappings.put(')','(');
        this.mappings.put('}','{');
        this.mappings.put(']','[');
    }
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<Character>();
        for(int i = 0; i<s.length(); i++){
            char c = s.charAt(i);
            //"(([(])))"
            if(this.mappings.containsKey(c)) {
                char topElement = stack.empty() ? '#' : stack.pop();
                if(topElement != this.mappings.get(c)){
                    return false;
                }
            }else {
                stack.push(c);
            }
        }
        return stack.isEmpty();
    }
}

/*复杂方法,可能和我想的方法相同*/
class Solution {
    public boolean isValid(String s) {
        int topIndex = -1;
        char[] stack = new char[s.length()];
        for (int i = 0; i < s.length(); i++) {
            char c1 = s.charAt(i);
            switch (c1) {
                case 40:
                    stack[++topIndex] = c1;
                    continue;
                case 91:
                    stack[++topIndex] = c1;
                    continue;
                case 123:
                    stack[++topIndex] = c1;
                    continue;
            }
            if (topIndex < 0) {
                return false;
            }
            switch (stack[topIndex] + c1) {
                case 81:
                    topIndex--;
                    continue;
                case 184:
                    topIndex--;
                    continue;
                case 248:
                    topIndex--;
                    continue;
                default:
                    return false;
            }
        }
        return topIndex == -1;
    }
}
9.合并两个链表
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { 
 *		   val = x;
 *	   }
 * }
 */
class Solution {
    /*这是个链表,创建的是链表,类似于数组,也许没有下标,但是可以相对遍历很多个元素,这个链表可以调用next对象,next对象又是一个相对来说小的链表,类似于LinkedList,LinkedList是一个有首尾的圆形链表,这个是只有开头的直线链表,这个链表和List类的链表不同,他没有继承List类(或者是接口),没办法使用迭代器。*/
   public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode res = new ListNode(0);
        ListNode re = res;
        int t = 0;
        if(l1 == null && l2 == null){
            res = null;
            return res;
        }
        while (l1!=null || l2!=null) {          
            if (l1 == null) {
                t = l2.val;
                l2 = l2.next;
            } else if(l2 == null){
                t = l1.val;
                l1 = l1.next;
            } else if(l2.val >= l1.val){
                t = l1.val;
                l1 = l1.next;
            } else{
                t = l2.val;
                l2 = l2.next;
            }
            re.val = t;
            if(l1 == null && l2 == null)
                break;
            re.next = new ListNode(0);
            re = re.next;   
        }
        return res;
    }
}

二、数组

1、删除排序数组中的重复项
/*给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。*/
/*如何处理重复项,置为null值
	   i
	[1,2,1,2,2,2,3]
	             j
*/
class Solution {
    public int removeDuplicates(int[] nums) {
        int i = 0;
        int j = 1;
        if (nums.length==0||nums==null){
            return 0;
        }
        while (j<nums.length){
            if (nums[i]==nums[j]){
                j++;
            } else{
                nums[i+1] = nums[j];
                i++;
                j++;
            }             
        }
        return i+1;
    }
}
2.买卖股票的最佳时机
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
/*多种组合
	             i
	[7,1,5,6,8,7,3,6,7,4,1,5,6,8]
	                 j 
	这个题的关键应该寻找一组组数据,寻找最优化数据组来使得每组数据差的总和最大
    
*/
class Solution {
    public int maxProfit(int[] prices) {
        int count=0;
        int i = 0;
        int j = 1;
        while(i<prices.length&&j<prices.length){
            if (prices[i]>prices[i+1]){
				i++;
				j++;
				continue;
            }
            if (j==prices.length-1){
            	count += prices[j]-prices[i];
            	return count;
            }
            if (prices[j]<prices[j+1]){
            	j++;
            	continue;
            } else{
                count += prices[j]-prices[i];
                i = j+1;
                j = i+1;
            }
        }
        return count;
    }
}
其他人的方法
class Solution {
    public int maxProfit(int[] prices) {
        if(prices==null || prices.length<=1) return 0;
        int i=0;
        int valley=prices[0];
        int peak=prices[0];
        int maxprofit=0;
        while(i<prices.length-1){
            while(i<prices.length-1 && prices[i]>=prices[i+1]){
                i++;
            }
            valley=prices[i];//gu
            while(i<prices.length-1 && prices[i]<=prices[i+1]){
                i++;
            }
            peak=prices[i];//feng
            maxprofit +=peak-valley;
        }
        return maxprofit;
    }
}
3.旋转数组
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
/*
	 i
	[1,2,3,4,5,6,7]
		   3
	[             ]
*/
class Solution {
    public void rotate(int[] nums, int k) {
        int[] res = new int[nums.length];
        int j = 0;
        for(int i=0;i<nums.length;i++){
            j = k+i;
            while(j>nums.length-1){
                j = j-nums.length;
            }
            res[j] = nums[i];
        }
        nums = res;
    }
}
class Solution {
    public void rotate(int[] nums, int k) {
        k=k%nums.length;
        int[] tmp=nums.clone();
        System.arraycopy(tmp,tmp.length-k,nums,0,k);
        System.arraycopy(tmp,0,nums,k,tmp.length-k);
    }
}
4.存在重复
给定一个整数数组,判断是否存在重复元素。
如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 falseclass Solution {
    public boolean containsDuplicate(int[] nums) {
        Arrays.sort(nums);
        for(int i=0;i<nums.length-1;i++){
            if(nums[i]==nums[i+1]){
				return true;
            }
        }
        return false;
    }
}
5.只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
/*
	[1,1,2,2,2,2,3,4,4,5,5]
*/
class Solution {
    public int singleNumber(int[] nums) {
        Arrays.sort(nums);
        for(int i=0;i<nums.length-1;i+=2){
            if(nums[i]!=nums[i+1]){
				return nums[i];
            }
        }
        return nums[nums.length-1];
    }
}
class Solution {
    public int singleNumber(int[] nums) {
        int single = 0;
        for(int i = 0;i < nums.length; i++){
            single = single ^ nums[i];
        }
        return single;
    }
}
6.两个数组的交集
给定两个数组,编写一个函数来计算他们的交集
class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int i=0;
        int j=0;
        int n=0;
        int[] res = new int[Math.min(nums1.length,nums2.length)];
        while(i<nums1.length&&j<nums2.length){
            if(nums1[i]==nums2[j]){
				res[n] = nums1[i];
				i++;
				j++;
				n++;
             } else if(nums1[i]<nums2[j]){
                i++;
             } else{
                j++;
             }
        }
        return res;
    }
}
7.加一
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
/*处理9999*/
class Solution {
    public int[] plusOne(int[] digits) {
    	int l = digits.length;      
        for(int i=l-1;i>=0;i--){
			if(digits[i]!=9){
                digits[i]++;
                return digits;
       		} 
       		digits[i] = 0;
        }
        digits = new int[l+1];
        digits[0] = 1;
  		return digits;
    }
}
8.移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
	 i
	[0,1,0,3,12]
    		 j
/*冒泡排序的阉割版*/
class Solution {
    public void moveZeroes(int[] nums) {
    if(){
    
    }
        int i = 0;
        int j = 1;
        while(j<nums.length&&i<j){
        if{
        
        }
            if (nums[i]==0) {
                if (nums[j]!=0) {
                    nums[i] = nums[j];
                    nums[j] = 0;
                    i++;
                    j++;
                } else{
                    j++;
                } 
            } else{
                i++;
                j++;
            }
        }
    }
}
9.两数之和
给定一个整数数组 nums和一个目标值 target, 请你在该数组中找出和为目标值的那 两个整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
/*
    nums = [2, 7, 11, 15], target = 9
*/
垃圾求和方式,这是垃圾
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] res = new int[2];
        for(int i=0;i<nums.length-1;i++){
            for(int j=i+1;j<nums.length-1;j++){
                if(nums[i]+nums[j]==target){
                    res[0] = i;
                    res[1] = j;
                    return res;
                }
            }
        }
        return res;
    }
}
//HashMap方式
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int ss = 0;
        HashMap<Integer,Integer> map = new HashMap<>();
        for(int i=0;i<nums.length;i++){
            ss = target - nums[i];
            if(map.containsKey(ss)){
                return new int[]{map.get(ss),i};
            }
            map.put(nums[i],i);
        }
        return null;
    }
}

10.有效的数独
判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

说明:
一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。
给定数独序列只包含数字 1-9 和字符 '.' 。
给定数独永远是 9x9 形式的。
/*
    如何处理二维数组,二维数组的行是一个数组,列用来遍历行数组。
*/
class Solution {
    public boolean isValidSudoku(char[][] board) {
        HashSet<Character> set = new HashSet<>();
        for (int i=0;i<board.length;i++) {
            for(int j=0;j<char[i][].length;j++){
                if(char[i][j].equals('.')){
                    continue;
                }
                if(set.contains(char[i][j])){
                    return false;
                }
                set.put(char[i][j]);
            }
            set.clear();
        }
        for (int i=0;i<board.length;i++) {
            for(int j=0;j<char[][i].length;j++){
                if(char[j][i].equals('.')){
                    continue;
                }
                if(set.contains(char[j][i])){
                    return false;
                }
                set.put(char[j][i]);
            }
            set.clear();
        }
        
        return true;
    }
}
/*渣渣,看别人是咋写的*/
class Solution {
    public boolean isValidSudoku(char[][] board) {
        boolean[][] row = new boolean[9][9];
        boolean[][] col = new boolean[9][9];
        boolean[][][] grid = new boolean[3][3][9];
        for(int i=0; i<9; i++){
            for(int j=0; j<9; j++){
                if(board[i][j] == '.')continue;
                int n = board[i][j] - 49;
                if(row[i][n] || col[j][n] || grid[i/3][j/3][n]) return false;
                row[i][n] = true;
                col[j][n] = true;
                grid[i/3][j/3][n] = true;
            }
        }
        return true;
    }
}

三、字符串

####1.反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
/*
      i
    ["h","e","l","l","o"]
                      j
*/
class Solution {
    public void reverseString(char[] s) {
        char c = '';
        for (int i=0,j=s.length-1;i<j;i++,j-- ) {
            c = s[i];
            s[i] = s[j];
            s[j] = c;
        }
    }
}

####2.字符串中的第一个唯一字符

给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,
返回-1
class Solution {
    public int firstUniqChar(String s) {
        HashMap<Character,Integer> map = new HashMap<>();
        int j = 0;
        char c = ' ';
        
        return j;
    }
}

class Solution {
    public   int firstUniqChar(String s){
        char []cs = s.toCharArray();
        char []record = new char[26];
        int index = 0;
        //统计
        for (char c : cs) {
            record[c - 'a']++;
        }//这句话就是用来统计的,比如出现了字符为a,那么a-a就是0,在数组record[0]自增,这个位置的记录就变成了1
        //判断
        //下面是错误写法
//      for (int i = 0; i < record.length; i++) {  //这里不能用record,因为record有的位置是用的,如果z出现一次,i为26,返回的是26而不是String中字符的位置
//          if (record[i] == 1) {
//              return i;
//          }
//      }
        
        for (int i = 0; i < cs.length; i++) {
            if (record[cs[i] - 'a'] == 1) {
                return i;
            }
        }
        return -1;
    }
}
这是最简单的方法
class Solution {
    public int firstUniqChar(String s) {
        int res = -1;
        for(char ch = 'a'; ch <= 'z'; ch++){
            int index = s.indexOf(ch);
            if(index != -1 && index == s.lastIndexOf(ch)){
                res = (res == -1 || res > index) ? index : res;
            }
        }
        return res;
    }
}

####3.有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的一个字母异位词。
说明:
你可以假设字符串只包含小写字母。

class Solution {
    public boolean isAnagram(String s, String t) {
        if (s.length != t.length) {
        	return false;
        }
        char[] sh = s.toCharArray();
        char[] th = t.toCharArray();
        char c = ' ';
        HashMap<Character,Integer> map = HashMap<>();
        for (int i=0;i<sh.length;i++ ) {
        	c = sh[i]
        	if (map.containsKey(c)) {
        		map.put(c,map.get()++)
        	} else {
        		map.put(c,1);
        	}
        }
        for (int i=0;i<th.length;i++ ) {
        	c = th[i]
        	if (map.containsKey(c)) {
        		map.put(c,map.get()--)
        		if(map.get(c)==0){
        			map.remove(c);
        		}
        	} else {
        		return false;
        	}
        }
        if (map.size == 0) {
        	return true;
        }
        return false;
    }
}
//其他方法
class Solution {
    public boolean isAnagram(String s, String t) {
        if (s.length() != t.length()) {
            return false;
        }
        int[] chars = new int[26];
        for(int i=0;i<s.length();i++){
            chars[s.charAt(i)-'a']++;
            chars[t.charAt(i)-'a']--;
        }
        for(int c:chars){
            if(c!=0){
                return false;
            }
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值