class Solution {
public int halveArray(int[] nums) {
PriorityQueue<Double> heap = new PriorityQueue<>((a, b) -> b.compareTo(a));// 大根堆-后比前
double sum = 0.0;
for (int x : nums) {
heap.offer((double) x);// 强转
sum += x;
}
sum /= 2.0;
int count = 0;
while (sum > 0) {
double t = heap.poll() / 2.0;
heap.offer(t);
sum -= t;
count++;
}
return count;
}
}
class Solution {
public String largestNumber(int[] nums) {
int n = nums.length;
String[] s = new String[n];
for (int i = 0; i < n; i++) {
s[i] = "" + nums[i];// 将整数数组转为字符串数组
}
Arrays.sort(s, (a, b) -> {// 重写排序
return (b + a).compareTo(a + b);// 返回最大数
});
StringBuffer ret = new StringBuffer();
for (String ss : s) {
ret.append(ss);// 对字符串数组中元素进行拼接(最大数)
}
if (ret.charAt(0) == '0')
return "0";
return ret.toString();
}
}
class Solution {
public int wiggleMaxLength(int[] nums) {
int n = nums.length, ret = 0, left = 0;
if (n < 2)
return 1;
for (int i = 0; i < n - 1; i++) {
int right = nums[i + 1] - nums[i];
if (right == 0)
continue;
if (left * right <= 0) {
ret++;
left = right;
}
}
return ret + 1;
}
}
class Solution {
public int lengthOfLIS(int[] nums) {
ArrayList<Integer> ret = new ArrayList<>();
int n = nums.length;
ret.add(nums[0]);// 先把nums中第一个数放进去
for (int i = 0; i < n; i++) {
if (nums[i] > ret.get(ret.size() - 1)) {// 下一个数>ret中最后一个数
ret.add(nums[i]);
} else {
// <=最后一个数
// 二分插入位置
int left = 0, right = ret.size() - 1;
while (left < right) {
int mid = (left + right) / 2;
if (ret.get(mid) < nums[i])
left = mid + 1;
else
right = mid;
}
ret.set(left, nums[i]);
}
}
return ret.size();
}
}
class Solution {
public boolean increasingTriplet(int[] nums) {
ArrayList<Integer> ret = new ArrayList<>();
ret.add(nums[0]);
int n = nums.length;
for (int i = 1; i < n; i++) {
if (nums[i] > ret.get(ret.size() - 1)) {
ret.add(nums[i]);
} else {
int left = 0, right = ret.size() - 1;
while (left < right) {
int mid = (left + right) / 2;
if (ret.get(mid) < nums[i])
left = mid + 1;
else
right = mid;
}
ret.set(left, nums[i]);
}
}
return ret.size() >= 3 ? true : false;
}
}
优化:
java复制代码
class Solution {
public boolean increasingTriplet(int[] nums) {
int a = nums[0], b = Integer.MAX_VALUE;
int n = nums.length;
for (int i = 1; i < n; i++) {
if (nums[i] > b)
return true;
else if (nums[i] > a)
b = nums[i];
else
a = nums[i];
}
return false;
}
}
class Solution {
public int findLengthOfLCIS(int[] nums) {
int ret = 0, n = nums.length;
for (int i = 0; i < n;) {
int j = i + 1;
while (j < n && nums[j] > nums[j - 1])
j++;
ret = Math.max(ret, j - i);
i = j;// 循环内部直接更新下一个位置的起点 - 贪心
}
return ret;
}
}
class Solution {
public int maxProfit(int[] prices) {
int ret = 0, prevmin = Integer.MAX_VALUE;
for (int i = 0; i < prices.length; i++) {
ret = Math.max(ret, prices[i] - prevmin);// 更新结果
prevmin = Math.min(prevmin, prices[i]);// 更新最小值
}
return ret;
}
}
class Solution {
public int maxProfit(int[] prices) {
// 实现方式一:双指针
int ret = 0, n = prices.length;
for (int i = 0; i < n; i++) {
int j = i;
while (j + 1 < n && prices[j] < prices[j + 1])
j++;// 向后寻找上升的末端
ret += prices[j] - prices[i];
i = j;
}
return ret;
}
}
实现方式二:拆分交易,把一段交易拆分成一天一天
java复制代码
class Solution {
public int maxProfit(int[] prices) {
// 实现方式二:拆分成一天一天的形式
int ret = 0;
for (int i = 1; i < prices.length; i++) {
if (prices[i] > prices[i - 1]) {
ret += prices[i] - prices[i - 1];
}
}
return ret;
}
}
class Solution {
public int largestSumAfterKNegations(int[] nums, int k) {
int x = 0;
while (x < k) {
Arrays.sort(nums);
nums[0] = (-nums[0]);
x++;
}
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
return sum;
}
}
class Solution {
public int[] advantageCount(int[] nums1, int[] nums2) {
int n = nums1.length;
// 1. 排序
Arrays.sort(nums1);
Integer[] index2 = new Integer[n];
for (int i = 0; i < n; i++)
index2[i] = i;
Arrays.sort(index2, (i, j) -> {
return nums2[i] - nums2[j];
});
// 2. 田忌赛马
int[] ret = new int[n];
int left = 0, right = n - 1;
for (int x : nums1) {
if (x > nums2[index2[left]])
ret[index2[left++]] = x;
else
ret[index2[right--]] = x;// 废物利用最大化
}
return ret;
}
}
class Solution {
public int[] diStringMatch(String s) {
int n = s.length();
int[] ret = new int[n + 1];
int left = 0, right = n, i = 0;
while (left < right) {
if (s.charAt(i) == 'I') {
ret[i++] = left++;
} else {
ret[i++] = right--;
}
}
ret[n] = left; // 把最后一个数放进去
return ret;
}
}
class Solution {
public String optimalDivision(int[] nums) {
int n = nums.length;
StringBuffer ret = new StringBuffer();
if (n == 1) {
return ret.append(nums[0]).toString();
} else if (n == 2) {
return ret.append(nums[0]).append("/").append(nums[1]).toString();
} else {
ret.append(nums[0]).append("/(");
int i = 1;
while (i < n - 1) {
ret.append(nums[i++]).append("/");
}
ret.append(nums[n - 1]).append(")");
}
return ret.toString();
}
}
class Solution {
public int jump(int[] nums) {
int left = 0, right = 0, ret = 0, maxpos = 0, n = nums.length;
while (left <= right) {
if (maxpos >= n - 1)
return ret;
for (int i = left; i <= right; i++) {
maxpos = Math.max(maxpos, nums[i] + i);
}
left = right + 1;
right = maxpos;
ret++;
}
return -1;
}
}
class Solution {
public boolean canJump(int[] nums) {
int left = 0, right = 0, maxpos = 0, n = nums.length;
while (left <= right) {
if (maxpos >= n - 1)
return true;
for (int i = left; i <= right; i++) {
maxpos = Math.max(maxpos, nums[i] + i);
}
left = right + 1;
right = maxpos;
}
return false;
}
}
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int curgas = 0, tank = 0, n = gas.length, begin = 0;
int[] diff = new int[n];
for (int i = 0; i < n; i++) {
curgas += gas[i] - cost[i];
tank += gas[i] - cost[i];
if (tank < 0) {
begin = i + 1;
tank = 0;
}
}
return curgas >= 0 ? begin : -1;
}
}
class Solution {
public int monotoneIncreasingDigits(int n) {
// 把数字转化为字符数组
char[] s = Integer.toString(n).toCharArray();
int i = 0, m = s.length;
// 找到第一个递减的位置
while (i + 1 < m && s[i] <= s[i + 1])
i++;
if (i == m - 1)
return n;// 特殊情况
// 回退
while (i - 1 >= 0 && s[i] == s[i - 1])
i--;
s[i]--;
for (int j = i + 1; j < m; j++)
s[j] = '9';
return Integer.parseInt(new String(s));// 将字符数组转化为整型
}
}
class Solution {
public int brokenCalc(int start, int target) {
// 正难则反+贪心
int ret = 0;
while (target > start) {
if (target % 2 == 0)
target /= 2;
else
target += 1;
ret++;
}
return ret + start - target;
}
}
class Solution {
public int[][] merge(int[][] intervals) {
// 按照左端点排序
Arrays.sort(intervals, (v1, v2) -> {
return v1[0] - v2[0];
});
// 合并区间-求并集
int left = intervals[0][0], right = intervals[0][1];
List<int[]> ret = new ArrayList<>();
for (int i = 1; i < intervals.length; i++) {
int a = intervals[i][0], b = intervals[i][1];
if (a <= right) {// 有重叠部分-合并
right = Math.max(b, right);
} else {// 不能合并
ret.add(new int[] { left, right });// 把结果加入数组中
left = a;
right = b;
}
}
// 最后一个区间
ret.add(new int[] { left, right });
return ret.toArray(new int[0][]);// 不限行不限列
}
}
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
// 按左端点进行排序
Arrays.sort(intervals, (v1, v2) -> {
return v1[0] - v2[0];
});
// 贪心
int left = intervals[0][0], right = intervals[0][1];
int count = 0;
for (int i = 1; i < intervals.length; i++) {
int a = intervals[i][0], b = intervals[i][1];
if (a < right) {// 有重叠部分
right = Math.min(b, right);
count++;
} else {// 没有重叠部分
left = a;
right = b;
}
}
return count;
}
}
class Solution {
public int findMinArrowShots(int[][] points) {
// 按左端点排序
Arrays.sort(points, (v1, v2) ->
// return v1[0] - v2[0];
Integer.compare(v1[0], v2[0])// 防溢出
);
// 贪心
int ret = 0;
int left = points[0][0], right = points[0][1];
for (int i = 1; i < points.length; i++) {
int a = points[i][0], b = points[i][1];
if (a <= right) {
ret++;
right = Math.min(b, right);
} else {
left = a;
right = b;
}
}
return points.length - ret;
}
}
class Solution {
public int[] rearrangeBarcodes(int[] b) {
Map<Integer, Integer> hash = new HashMap<>();
int maxval = 0, maxcount = 0;
for (int x : b) {
hash.put(x, hash.getOrDefault(x, 0) + 1);
if (maxcount < hash.get(x)) {
maxcount = hash.get(x);
maxval = x;
}
}
int n = b.length;
int[] ret = new int[n];
int index = 0;
// 先处理出现次数最多的数
for (int i = 0; i < maxcount; i++) {
ret[index] = maxval;
index += 2;
}
hash.remove(maxval);
for (int x : hash.keySet()) {
for (int i = 0; i < hash.get(x); i++) {
if (index >= n)
index = 1;
ret[index] = x;
index += 2;
}
}
return ret;
}
}