Leetcode 相关知识点 day2
## /用于作者每日有需所作笔记
1. 动态规划求乘积最大子数组
常规的遍历求解容易超时;
class Solution {
public int maxProduct(int[] nums) {
int maxF = nums[0], minF = nums[0], ans = nums[0];
int length = nums.length;
for (int i = 1; i < length; ++i) {
int mx = maxF, mn = minF;
maxF = Math.max(mx * nums[i], Math.max(nums[i], mn * nums[i]));
minF = Math.min(mn * nums[i], Math.min(nums[i], mx * nums[i]));
ans = Math.max(maxF, ans);
}
return ans;
}
}
Math.max方法
2. Arrays类的常用方法
2.1 Arrays.fill(); //填充数组
**2.1 Arrays.fill(); //填充数组**
int[] arr = new int[5];//新建一个大小为5的数组
Arrays.fill(arr,4);//给所有值赋值4
String str = Arrays.toString(arr); // Arrays类的toString()方法能将数组中的内容全部打印出来
System.out.print(str);
//输出:[4, 4, 4, 4, 4]
int[] arr = new int[5];//新建一个大小为5的数组
Arrays.fill(arr, 2,4,6);//给第2位(0开始)到第4位(不包括)赋值6
String str = Arrays.toString(arr); // Arrays类的toString()方法能将数组中的内容全部打印出来
System.out.print(str);
//输出:[0, 0, 6, 6, 0]
**2.2 Arrays.sort(); //数组排序**
int[] intArray = new int[] { 4, 1, 3, -23 };
Arrays.sort(intArray);
//输出: [-23, 1, 3, 4]
*字符串排序,先大写后小写*
String[] strArray = new String[] { “z”, “a”, “C” };
Arrays.sort(strArray);
//输出: [C, a, z]
严格按字母表顺序排序,
也就是忽略大小写排序 Case-insensitive sort
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
//输出: [a, C, z]
反向排序, Reverse-order sort
Arrays.sort(strArray, Collections.reverseOrder());
//输出:[z, a, C]
忽略大小写反向排序
Case-insensitive reverse-order sort
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
Collections.reverse(Arrays.asList(strArray));
//输出: [z, C, a]
选择数组指定位置进行排序
int[] arr = {3,2,1,5,4};
Arrays.sort(arr,0,3);//给第0位(0开始)到第3位(不包括)排序
String str = Arrays.toString(arr); // Arrays类的toString()方法能将数组中的内容全部打印出来
System.out.print(str);
//输出:[1, 2, 3, 5, 4]
**2.3 Arrays.toString(); //数组打印**
int[] arr = {3,2,1,5,4};
System.out.print(arr);//直接将数组打印输出
//输出:[I@7852e922 (数组的地址)
String str = Arrays.toString(arr); // Arrays类的toString()方法能将数组中的内容全部打印出来
//System.out.print(str);
//输出:[3, 2, 1, 5, 4]
**2.4 Arrays.equals(); //数组比较**
int[] arr1 = {1,2,3};
int[] arr2 = {1,2,3};
System.out.println(Arrays.equals(arr1,arr2));
//输出:true
//如果是arr1.equals(arr2),则返回false,因为equals比较的是两个对象的地址,不是里面的数,而Arrays.equals重写了equals,所以,这里能比较元素是否相等。
**2.5 Arrays.binarySearch(); //数组查找**
二分查找法找指定元素的索引值(下标)
Arrays.binarySearch();
数组一定是排好序的,否则会出错。找到元素,只会返回最后一个位置
int[] arr = {10,20,30,40,50};
System.out.println(Arrays.binarySearch(arr, 30));
//输出:2 (下标索引值从0开始)
int []arr = {10,20,30,40,50};
System.out.println(Arrays.binarySearch(arr, 0,3,40));
//输出:-4 (从0到3位(不包括)找40,找不到,从-1开始数,返回-4)
int []arr = {10,20,30,40,50};
System.out.println(Arrays.binarySearch(arr, 0,3,30));
//输出:2 (从0到3位(不包括)找30,找到了,在第2位,返回2)
**2.6 Arrays.copyOf() 和Arrays.copyOfRange(); //数组截取**
int[] arr = {10,20,30,40,50};
int[] arr1 = Arrays.copyOf(arr, 3);
String str = Arrays.toString(arr1); // Arrays类的toString()方法能将数组中的内容全部打印出来
System.out.print(str);
//输出:[10, 20, 30] (截取arr数组的3个元素赋值给新数组arr1)
int []arr = {10,20,30,40,50};
int []arr1 = Arrays.copyOfRange(arr,1,3);
String str = Arrays.toString(arr1); // Arrays类的toString()方法能将数组中的内容全部打印出来
System.out.print(str);
//输出:[20, 30] (从第1位(0开始)截取到第3位(不包括))
**2.7 实现高效率的数组之间的复制,用它来复制数组比用for循环复制快很多**
//将原数组(str1)从0到往后复制str1.length个长度到目标数组(str2)中,从目标数组索引为0的位置开始放置
System.arraycopy(str1,0,str2,0,str1.length);//A B C D E null null null null null
//将原数组(str1)从0到往后复制str1.length个长度到目标数组(str2)中,从目标数组索引为2的位置开始放置
System.arraycopy(str1,0,str2,2,str1.length);//null null A B C D E null null null
//将原数组(str1)从1到往后复制str1.length-1个长度到目标数组(str2)中,从目标数组索引为0的位置开始放置
System.arraycopy(str1,1,str2,0,str1.length-1);//B C D E null null null null null null
//将原数组(str1)从1到往后复制str1.length-2个长度到目标数组(str2)中,从目标数组索引为0的位置开始放置
System.arraycopy(str1,1,str2,0,str1.length-2);//B C D null null null null null null nu
字符串转字符串组再转列
String[] dataArray = data.split(",");
List<String> dataList = new LinkedList<String>(Arrays.asList(dataArray));
3. 数组翻转
4. hashset()
Set<Integer> set1 = new HashSet<>();
set.add(); 已存在返回false;
set.contains();
set.size()
遍历set集合
for (String i : sites) {
System.out.println(i);
}
5. 涉及数组移动
常用双指针法
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
class Solution {
public void moveZeroes(int[] nums) {
int i = 0, j = 0;
while (j < nums.length) {
if (nums[j] == 0) {
j++;
continue;
}
nums[i++] = nums[j++];
}
for (int k = i; k < j; k++) {
nums[k]=0;
}
}
}
6. 随机数
Random random = new Random();
return random.nextInt(size);
返回 0到size范围内的随机数,包含0,不包含size
7. MAP
***统计两个数组的交集,数目按较少的来!***
首先遍历第一个数组,并在哈希表中记录第一个数组中的每个数字以及对应出现的次数,
然后遍历第二个数组,对于第二个数组中的每个数字,如果在哈希表中存在这个数字,
则将该数字添加到答案,并减少哈希表中该数字出现的次数。
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
if (nums1.length > nums2.length) {
return intersect(nums2, nums1);
}
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int num : nums1) {
int count = map.getOrDefault(num, 0) + 1;
map.put(num, count);
}
int[] intersection = new int[nums1.length];
int index = 0;
for (int num : nums2) {
int count = map.getOrDefault(num, 0);
if (count > 0) {
intersection[index++] = num;
count--;
if (count > 0) {
map.put(num, count);
} else {
map.remove(num);
}
}
}
return Arrays.copyOfRange(intersection, 0, index);
}
}
注:当键值相同,map会覆盖原先数据
Set<Integer> set1 = new HashSet<>();
map.put(5,4);
map.put(8,0);
map.put(5,1);
输出{5=1, 8=0}
8. 递增三元子序列
给你一个整数数组 nums ,判断这个数组中是否存在长度为 3 的递增子序列。如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k ,使得 nums[i] < nums[j] < nums[k] ,返回 true ;否则,返回 false。
常规做法是 分别定义两个数组,存储当前位置左边最小值和右边最大值。
class Solution {
public boolean increasingTriplet(int[] nums) {
int[] less = new int[nums.length]; //记录左边最小值
int[] more = new int[nums.length]; //记录右边最大值
less[0] = nums[0];
more[nums.length-1] = nums[nums.length-1];
for(int i=1;i<nums.length;i++){
less[i] = Math.min(less[i-1],nums[i]);
}
for(int i=nums.length-2;i>=0;i--){
more[i] = Math.max(more[i+1],nums[i]);
}
for(int i=1;i<nums.length-1;i++){
if(nums[i]>less[i] && nums[i]<more[i]){
return true;
}
}
return false;
}
}
方法二较为巧妙。
class Solution {
public boolean increasingTriplet(int[] nums) {
if (nums == null || nums.length < 3) return false;
int l = nums[0], m = Integer.MAX_VALUE;
for (int n : nums)
if (n <= l) l = n;
else if (n <= m) m = n;
else return true;
return false;
}
}
原理在于只遍历一次,而我们遍历寻找的是三元子序列最后一个。
核心就在于寻找的第三个数是大于前两个数,并且另外两个数也是满足条件最小的,
一旦指针确定下来前两个数(非初始),必定满足递增,则只需找第三个数。
9. Set
Set<String> set1 = new HashSet<>();
set1.add("1");
set1.add("8");
set1.add("5");
set1.add("1");
System.out.println(set1);
结果[1,5,8]
取值只能通过set转数组
String[] arr = set1.toArray(new String[set1.size()]);
int 和 string 转换
Integer.valueOf()
String.valueOf()
10. Queue
PriorityQueue<Integer> queMin;
PriorityQueue<Integer> queMax;
queMin = new PriorityQueue<Integer>((a, b) -> (b - a)); //从小到大排序 栈顶最大
queMax = new PriorityQueue<Integer>((a, b) -> (a - b)); //从大到小排序
PriorityQueue<Long> pq1 = new PriorityQueue<>((o1,o2) -> {
if (o2 - o1 > 0) return 1;
if (o2.equals(o1)) return 0;
return -1;
});//大顶堆