leecode更新

This commit is contained in:
markilue 2023-02-10 13:56:51 +08:00
parent 5c54b530f4
commit f72765f983
5 changed files with 312 additions and 1 deletions

View File

@ -0,0 +1,148 @@
package com.markilue.leecode.greedy;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.greedy
*@Author: markilue
*@CreateTime: 2023-02-10 11:01
*@Description:
* TODO 力扣406题 根据身高重建队列:
* 假设有打乱顺序的一群人站成一个队列数组 people 表示队列中一些人的属性不一定按顺序
* 每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi 前面 正好 ki 个身高大于或等于 hi 的人
* 请你重新构造并返回输入数组 people 所表示的队列
* 返回的队列应该格式化为数组 queue 其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性queue[0] 是排在队列前面的人
*@Version: 1.0
*
*/
public class T10_1_ReconstructQueue {
@Test
public void test() {
// int[][] people = new int[][]{{7, 0}, {4, 4}, {7, 1}, {5, 0}, {6, 1}, {5, 2},{4,1}};
int[][] people = new int[][]{{6, 0}, {5, 0}, {4, 0}, {3, 2}, {2, 2}, {1, 4}};
reconstructQueue(people);
}
/**
* 思路:先升序排列一下,再反向腾挪位置
* 速度击败78.37%内存击败73.68% 6ms
* @param people
* @return
*/
public int[][] reconstructQueue(int[][] people) {
//升序排列一下
Arrays.sort(people, (array1, array2) -> {
return array1[0] != array2[0] ? array1[0] - array2[0] : array1[1] - array2[1];
});
//反向遍历挪位置
for (int i = people.length - 1; i >= 0; i--) {
//统计前面有多少个相等的数看看这个值与people[i][1]是否相等
int count = 0;
for (int j = i - 1; j >= 0; j--) {
if (people[j][0] == people[i][0]) {
count++;
} else break;
}
//不等于就需要向后挪动
if (people[i][1] != count) {
int[] cur = people[i];
int index = people[i][1] - count;
if (i + index < people.length) {
System.arraycopy(people, i + 1, people, i, index);
people[i + index] = cur;
}
}
}
return people;
}
/**
* 代码随想录思路:本质上一致就是分别考虑两个维度想考虑身高在考虑位置
* 不过与本人不同的是他是先由大到小排列然后使用linkedList一个一个插入
* 时间击败67.5% 内存击败47.51% 7ms
* @param people
* @return
*/
public int[][] reconstructQueue1(int[][] people) {
// 身高从大到小排身高相同k小的站前面
Arrays.sort(people, (a, b) -> {
if (a[0] == b[0]) return a[1] - b[1];
return b[0] - a[0];
});
LinkedList<int[]> que = new LinkedList<>();
for (int[] p : people) {
que.add(p[1],p);
}
return que.toArray(new int[people.length][]);
}
/**
* 官方最快:2ms
* 本质上只是自己实现了快排来进行排序
* @param people
* @return
*/
public int[][] reconstructQueue2(int[][] people) {
int len = people.length;
quickSort(people, 0, len - 1);
List<int[]> ans = new ArrayList<int[]>();
for (int[] person : people) {
ans.add(person[1], person);
}
return ans.toArray(new int[ans.size()][]);
}
private void quickSort(int[][] array, int left, int right){
if(left >= right){
return;
}
int i = left, j = right;
int[] temp = array[left];
int index = left;
while(i < j){
while(i < j && compareValue1(array[i], temp)){
i++;
}
while(i < j && !compareValue1(array[j], temp)){
j--;
}
if(i < j){
int[] t = array[i];
array[i] = array[j];
array[j] = t;
}
if(array[i] == temp){
index = i;
}else if(array[j] == temp){
index = j;
}
}
array[index] = array[i];
array[i] = temp;
quickSort(array, left, i - 1);
quickSort(array, i + 1, right);
}
private boolean compareValue1(int[] a, int[] b){
if(a[0] == b[0]){
return a[1] < b[1];
}else{
return a[0] > b[0];
}
}
}

View File

@ -17,7 +17,7 @@ import java.util.HashMap;
* 给你一个整数数组 bills 其中 bills[i] 是第 i 位顾客付的账如果你能给每位顾客正确找零返回 true 否则返回 false * 给你一个整数数组 bills 其中 bills[i] 是第 i 位顾客付的账如果你能给每位顾客正确找零返回 true 否则返回 false
* @Version: 1.0 * @Version: 1.0
*/ */
public class LemonadeChange { public class T10_LemonadeChange {
@Test @Test
public void test(){ public void test(){

View File

@ -1,5 +1,9 @@
package com.markilue.leecode.greedy.second; package com.markilue.leecode.greedy.second;
import org.junit.Test;
import java.util.Arrays;
/** /**
*@BelongsProject: Leecode *@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.greedy.second *@BelongsPackage: com.markilue.leecode.greedy.second
@ -16,7 +20,47 @@ package com.markilue.leecode.greedy.second;
*/ */
public class T09_Candy { public class T09_Candy {
@Test
public void test() {
int[] ratings = {1, 0, 2};
System.out.println(candy(ratings));
}
/**
* 思路:需要知道左右分别需要这个位置最少是多少然后两者中取大两次贪心
* 本质上不算我过得还有有点印象看过答案
* 速度击败98.68% 内存击败58%
* @param ratings
* @return
*/
public int candy(int[] ratings) { public int candy(int[] ratings) {
int[] leftMin = new int[ratings.length];
leftMin[0] = 1;
//记录左边递增序列每个位置最少需要多少向右贪心
for (int i = 1; i < ratings.length; i++) {
if (ratings[i] > ratings[i - 1]) {
leftMin[i] = leftMin[i - 1] + 1;
}else {
leftMin[i]=1;
}
}
int result = 0;
int lastNeed = 1;
//向左贪心记录每个位置最少需要加在总和里
for (int i = ratings.length - 1; i >= 0; i--) {
if (i != ratings.length - 1 && ratings[i] > ratings[i + 1]) {
lastNeed = lastNeed + 1;
} else {
lastNeed = 1;
}
result += Math.max(leftMin[i], lastNeed);
}
return result;
} }
} }

View File

@ -0,0 +1,50 @@
package com.markilue.leecode.greedy.second;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.greedy.second
*@Author: markilue
*@CreateTime: 2023-02-10 10:47
*@Description:
* TODO 力扣860 柠檬水找零:
* 在柠檬水摊上每一杯柠檬水的售价为 5 美元顾客排队购买你的产品按账单 bills 支付的顺序一次购买一杯
* 每位顾客只买一杯柠檬水然后向你付 5 美元10 美元或 20 美元你必须给每个顾客正确找零也就是说净交易是每位顾客向你支付 5 美元
* 注意一开始你手头没有任何零钱
* 给你一个整数数组 bills 其中 bills[i] 是第 i 位顾客付的账如果你能给每位顾客正确找零返回 true 否则返回 false
*@Version: 1.0
*/
public class T10_LemonadeChange {
/**
* 思路:有大钱先用大钱没大钱用小钱因为小钱可以找开所有
* @param bills
* @return
*/
public boolean lemonadeChange(int[] bills) {
int[] count = new int[3];//5,10,20的count
for (int i = 0; i < bills.length; i++) {
if (bills[i] == 5) {
count[0]++;
continue;
}
if(bills[i]==10){
count[0]--;
count[1]++;
}else {
//最难讨论的
if(count[1]>0){
count[1]--;
count[0]--;
}else {
count[0]-=3;
}
}
if(count[0]<0)return false;
}
return true;
}
}

View File

@ -0,0 +1,69 @@
package com.markilue.leecode.sort;
import org.junit.Test;
import java.util.Arrays;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.sort
*@Author: markilue
*@CreateTime: 2023-02-10 12:18
*@Description: TODO 自己实现快排:
*@Version: 1.0
*/
public class QuickSort {
@Test
public void test(){
int[] nums={8,5,3,7,6,4,1,9};
quickSort(nums,0,nums.length-1);
System.out.println(Arrays.toString(nums));
}
public void quickSort(int[] nums, int left, int right) {
if(left>=right)return;
int mid = partition(nums, left, right);
quickSort(nums, left, mid - 1);
quickSort(nums, mid + 1, right);
}
/**
* 寻找num[left]的合适的位置
* @param nums
* @param left
* @param right
*/
public int partition(int[] nums, int left, int right) {
if (left >= right) return left;
int start = left + 1;
int end = right;
while (start <= end) {
while (start < right && nums[start] < nums[left]) {
start++;
}
while (end > left && nums[end] > nums[left]) {
end--;
}
if(start>=end)break;
//找到两个需要交换的值
swap(nums, start, end);
start++;
end--;
}
swap(nums, left, end);
return end;
}
public void swap(int[] nums, int left, int right) {
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
}
}