Leetcode java 入门2

1365. 有多少小于当前数字的数字

给你一个数组 nums,对于其中每个元素 nums[i],请你统计数组中比它小的所有数字的数目。
换而言之,对于每个 nums[i] 你必须计算出有效的 j 的数量,其中 j 满足 j != i 且 nums[j] < nums[i] 。

以数组形式返回答案。
输入:nums = [8,1,2,2,3]
输出:[4,0,1,1,3]
暴力解法

class Solution {
    public int[] smallerNumbersThanCurrent(int[] nums) {
        int leslie;
        int jk=0;
        int [] faye=new int [nums.length];
        for (int i=0;i<nums.length;i++){
            leslie=0;
            for (int j=0;j<nums.length;j++){
                if (j!=i){
                    if (nums[j]<nums[i])
                        leslie++;
                }
            }
            faye[jk]=leslie;
            jk++;
        }
        return faye;
    }
}

时间:O(n^2) 空间O(1)

2.计数排序

public int[] smallerNumbersThanCurrent(int[] nums) {
	int [] faye= new int [101];
	for (int i = 0; i < nums.length; i++) {
		faye[nums[i]] +=1;        //统计数字出现频率{0,1,2,1,0,0,0,0,1}
	}
	for (int i = 1; i < faye.length; i++) {
		faye[i] += faye[i-1];    //{0,1,3,4,4,4,4,4,5} 累加前面数
	}							 // 0 1 2 3 4 5 6 7 8
	for (int i = 0; i < nums.length; i++) {
		nums[i] = nums[i]!=0  ?  faye[nums[i]-1] : 0;
	} //找到累加数组的前一个数即为前面小于它的数的总和
	return nums;
}

时间复杂度:O(N + K),其中 K 为(数组)值域大小。需要遍历两次原数组,同时遍历一次频次数组找出前缀和。
空间复杂度:O(K),因为要额外开辟一个值域大小的数组。

3.排序加哈希图

class Solution {
    public static int[] smallerNumbersThanCurrent(int[] nums) {
	int [] faye=Arrays.copyOf(nums, nums.length); //数组复制
	Arrays.sort(faye);// {1,2,2,3,8}
	HashMap<Integer, Integer> leslie = new HashMap<>();
	for (int i = faye.length-1; i >=0; i--) {
		leslie.put(faye[i], i);  //相同的数被赋予下标
		//(8,4)(3,3)(2,2)(2,1)(1,0)
	 //从后往前排 同样值必须让低索引覆盖高索引 索引计算排第几才有意义
	}
	for (int i = 0; i < faye.length; i++) {
		nums[i]=leslie.get(nums[i]);//nums里的数值对应hash表的key输出value
	}
	return nums;
}
}

时间复杂度 O(nlog(n)),空间复杂度 O(n)
解释
1.Arrays.sort()排序的复杂度为O(nlog(n))。
2.开辟了Faye的新数组空间为N
3.Arrays.copyOf(les[], les.length) 完全复制一个新数组

1002.查找常用字符

给定仅有小写字母组成的字符串数组 A,返回列表中的每个字符串中都显示的全部字符(包括重复字符)组成的列表。例如,如果一个字符在每个字符串中出现 3 次,但不是 4 次,则需要在最终答案中包含该字符 3 次。

你可以按任意顺序返回答案。
输入:[“bella”,“label”,“roller”]
输出:[“e”,“l”,“l”]

1.字符计数解法

涉及Linklist 双向链表,计数排序
Character.toString(char)方法char->String
s.toCharArray() 转字符串为字符数组
在这里插入图片描述

import java.util.List;
//如果是import java.awt.List;报错类型 List 不是通用的,不能使用参数() 将它参数化
 	public static List commonChars(String[] A) {
		int [] leslie = getAs(A[0]);  //把[0]字符串 转为计数频率数组
		List<String> faye=new LinkedList<String>();  
		for (int i = 1; i < A.length; i++) {
			int [] leslie2 = getAs(A[i]); //找到第二组字符串{0111010}
			
			for (int j = 0; j < leslie.length; j++) {
				if(leslie[j]>leslie2[j])  		//只要leslie2的值不为0,就会保证leslie中出现过相同字符。
					leslie[j]=leslie2[j];//如果leslie2有值为0,则leslie相应的值为0。  
			}		
		}//for 循环后得到一组计算数组 记录字符串的频率。
		
	
		for (int j = 0; j < leslie.length; j++) {
			String e=null;
			//if(leslie[j]>0)	
			while(leslie[j]-- >0)//成功解决出现两次字母的问题 判断>0再自--判断
			{
			// Character.toString(char)方法char->String
				e=Character.toString((char) (j+'a')); //int j + 'a' 强制类型转换会变成整数
				faye.add(e);
			}
		}
		return  faye;
	}	
	
		private static int[] getAs(String s) {  //统计字符出现次数
			int [] faye= new int [26];  								
			for (char i : s.toCharArray())
			{ 	//s.toCharArray() 转字符串为字符数组 
				faye[i-'a']++; 	
			}
			return faye;
		}

Java中的集合类的关系图
在这里插入图片描述

ArrayList与LinkedList区别
在这里插入图片描述

349.两个数组的交集

给定两个数组,编写一个函数来计算它们的交集。
示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
在这里插入图片描述

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Set<Integer> faye = new HashSet<>();
        Set<Integer> faye1 = new HashSet<>();
        Set<Integer> faye2 = new HashSet<>();
        int k= 0;
        
       // Integer []leslie = new Integer [nums2.length];
        for (int i = 0; i < nums1.length; i++) {
			faye.add(nums1[i]);
		}
        for (int i = 0; i < nums2.length; i++) {
        	faye1.add(nums2[i]);
		}
        faye2.addAll(faye);
        faye2.retainAll(faye1);//取集合交集
        int []leslie = new int [faye2.size()];
        for (int a : faye2) {
			leslie[k]=a;
			k++;
		}
        //leslie=faye2.toArray(new Integer[0]);
        //对象无法转类型
        return leslie;
}
}
136. 只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

输入: [4,1,2,1,2]
输出: 4
1.暴力解法

    public static int singleNumber(int[] nums) {
    int leslie=0;  
    for (int i = 0; i < nums.length; i++) {
		for (int j = 0; j < nums.length; j++) {
			if(i==j)  //避免自身比较
				continue;
			if (nums[i]==nums[j]) {
				leslie=1;  //哨兵找到相同元素
				break;
			}
			else leslie=0; //如果不置0 [2,2,1] 1的值无法找到
		}
		if (leslie==0) 
			return nums[i];
	}
    return 0;
    }

第一次写暴力解法花了40分钟!
在这里插入图片描述

2.异或运算
解题思路:
0⊕a =a
a⊕b⊕c =a⊕c⊕b(交换率)
4⊕3⊕5⊕3⊕4 等价于(4⊕4⊕3⊕3)⊕5 等价于0 ⊕ 5
题目中每个元素均出现两次 则满足上式子

class Solution {
    public static int singleNumber(int[] nums) {
        int faye = 0;
    	for (int i : nums) {
			faye ^= i;
		}//0异或任何数都为原值
    	return faye;
    }
}

异或时间复杂度为O(n),空间复杂度为O(1)
在这里插入图片描述3.HashMap实现

    public static int singleNumber(int[] nums) {//[4,1,2,1,2]
        HashMap<Integer,Integer> leslie = new HashMap<>();
		for (int i : nums) { //间接计数排序    (4,1) (1,2) (2,2)
			Integer count = leslie.get(i); //值如果不存在 则为null
			count = count == null? 1: ++count;//如果count++,则会把count赋给count,再加一导致bug。
			leslie.put(i, count); //(1,2) 会覆盖 (1,1)
		}
		for (int  j : leslie.keySet()) {//map.keySet()返回一个由键组成的集合
			if(leslie.get(j)==1)//值为1 则返回键key
				return j;
		}
    return -1;
    }

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值