10.16 10.17lc
:学渣综合征: 一道星期天 就像躺平。。。。。
刷了几道题: 主要回顾 排序
38. 外观数列 - 力扣(LeetCode) (leetcode-cn.com)
:外观数列 : 思路:就是对前一个数列: 进行总结: 相同跳过相加,不同
class Solution {
public String countAndSay(int n) {
String str = "1";
// 模拟的过程 所谓的 外观数列 其实就是 对上一个 字符串的 相同元素的描述
for(int i=2;i<=n;i++){
int start =0;
int pre =0;
// 子结果集
StringBuilder sb =new StringBuilder() ;
while(pre < str.length()){
// 相同 就往后走
while(pre < str.length() && str.charAt(pre) == str.charAt(start)){
pre++;
}
// 存下 相同的次数和 当前的start的字符
sb.append(Integer.toString(pre -start)).append(str.charAt(start));
start= pre;
}
// 结果集
str =sb.toString();
}
return str;
}
}
282. 给表达式添加运算符 - 力扣(LeetCode) (leetcode-cn.com)
:题都没看懂。。。。。。 《铁废物~》
912. 排序数组 - 力扣(LeetCode) (leetcode-cn.com)
快排 和 归并
//归并
class Solution {
public int[] sortArray(int[] nums) {
mergeSort(nums,0,nums.length-1,new int[nums.length]);
return nums;
}
//分割
public void mergeSort(int[] nums,int left ,int right,int[] temp){
if(left >= right) return;
int mid =left +((right-left)/2);
mergeSort(nums,left,mid,temp);
mergeSort(nums,mid+1,right,temp);
//合并
merge(nums,left,mid,right,temp);
}
private void merge(int[] nums, int left, int mid, int right, int[] temp) {
//这里的合并思路就是: 先赋值到 辅助空间 temp[] 在对原来的进行 覆盖修改
for (int i = left; i <= right ; i++) {
temp[i] = nums[i];
}
int l= left;
int r=mid+1;
for (int i = left; i <=right ; i++) {
//左边 完毕
if(l == mid+1) nums[i] =temp[r++];
//右边完毕
else if ( r== right+1) nums[i] =temp[l++];
//那边小 先放那边
else if (temp[l] <=temp[r]) nums[i] =temp[l++];
else nums[i]=temp[r++];
}
}
}
//快排: 这里使用的随机选取 pivot
class Solution {
public int[] sortArray(int[] nums) {
randomizedQuicksort(nums, 0, nums.length - 1);
return nums;
}
//主方法
public void randomizedQuicksort(int[] nums, int l, int r) {
if (l < r) {
int pos = randomizedPartition(nums, l, r);
randomizedQuicksort(nums, l, pos - 1);
randomizedQuicksort(nums, pos + 1, r);
}
}
//随机选择
public int randomizedPartition(int[] nums, int l, int r) {
int i = new Random().nextInt(r - l + 1) + l; // 随机选一个作为我们的主元
swap(nums, r, i);
return partition(nums, l, r);
}
//分区
public int partition(int[] nums, int l, int r) {
int pivot = nums[r];
int i = l - 1;
for (int j = l; j <= r - 1; ++j) {
if (nums[j] <= pivot) {
i = i + 1;
swap(nums, i, j);
}
}
swap(nums, i + 1, r);
return i + 1;
}
//交换元素
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
剑指 Offer 51. 数组中的逆序对 - 力扣(LeetCode) (leetcode-cn.com)
:归并排序的衍生题:
class Solution {
public int reversePairs(int[] nums) {
if(nums == null || nums.length <2){
return 0;
}
return mergeSort(nums,0,nums.length-1,new int[nums.length]);
}
public int mergeSort(int[] arr , int left, int right, int[] temp){
if(left>=right) return 0;
int mid =(left+right)/2;
int leftValues = mergeSort(arr, left, mid, temp);
int rightValues = mergeSort(arr, mid + 1, right, temp);
int Values = reverseMerage(arr, left, mid, right, temp);
return Values+leftValues+rightValues;
}
private int reverseMerage(int[] arr, int left, int mid, int right, int[] temp) {
for (int i = left; i <=right ; i++) {
temp[i] =arr[i];
}
int l= left;
int r=mid+1;
int count =0;
for (int i = left; i <= right ; i++) {
if(l == mid+1) arr[i]=temp[r++];
else if( r ==right+1) arr[i] =temp[l++];
else if (temp[l] <=temp[r]) arr[i] =temp[l++];
else {
//就是加了个 比较
arr[i] =temp[r++];
// 这个 count的计算
count+=mid-l+1;
}
}
return count;
}
}
230. 二叉搜索树中第K小的元素 - 力扣(LeetCode) (leetcode-cn.com)
:方法很多 : 中序遍历: 不是额外的空间来做
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private int cnt = 0;
private int ans = 0;
public int kthSmallest(TreeNode root, int k) {
f(root, k);
return ans;
}
public void f(TreeNode root, int k) {
if (root == null) return;
f(root.left, k);
cnt++;
if (cnt == k) {
ans = root.val;
return;
}
f(root.right, k);
}
}
剑指 Offer 03. 数组中重复的数字 - 力扣(LeetCode) (leetcode-cn.com)
:辅助空间:
class Solution {
public int findRepeatNumber(int[] nums) {
int[] arr= new int[nums.length];
for (int i = 0; i < nums.length; i++) {
arr[nums[i]]+=1;
}
for (int i = 0; i < arr.length; i++) {
if(arr[i] !=1 &&arr[i]!=0){
return i;
}
}
return 0;
}
}
剑指 Offer 53 - I. 在排序数组中查找数字 I - 力扣(LeetCode) (leetcode-cn.com)
:别问: 就是靠 二分~
class Solution {
public int search(int[] nums, int target) {
int count=0;
int l=0,r=nums.length-1;
while(l<r){
int mid =(l+r)/2;
if(nums[mid]>=target){
r=mid;
}
if(nums[mid] < target){
l=mid+1;
}
}
//找到 后 遍历找出现次数
while(l<nums.length && nums[l++] == target){
count++;
}
return count;
}
}
41. 缺失的第一个正数 - 力扣(LeetCode) (leetcode-cn.com)
:直接调用api就可以做:
class Solution {
public int firstMissingPositive(int[] nums) {
int len =nums.length;
Arrays.sort(nums);
for (int i=1;i<=len;i++){
//Arrays.binarySearch(nums,i) 在有序的 情况下 进行二分查找 没有 就是 负数
if(Arrays.binarySearch(nums,i)<0) return i;
}
return len+1;
}
}
:或者 辅助空间:
class Solution {
public int firstMissingPositive(int[] nums) {
if (nums.length == 0) {return 1;}
int[] res = new int[nums.length + 1];
for (int x : nums) {
if (x > 0 && x < res.length) {
res[x] = x;
}
// 少了个括号!!!!! 找了半天淦~
}
for (int i = 1; i < res.length; i++) {
if(res[i] != i) return i;
}
return res.length;
}
}
:或者桶排序: 不适用额外的空间
class Solution {
public int firstMissingPositive(int[] nums) {
if(nums.length == 0) return 1;
int n=nums.length;
for(int i=0 ; i<n ;i++){
// nums[i] 值 要在 【0 ,n+1】 && nums[i] 不能相同 && nums[i] 这个位置不是自己
while(nums[i]>0 && nums[i]<n+1 && nums[i]!=i+1 &&nums[nums[i]-1] !=nums[i]){
//讲 i 和原本的位置 进行交换
swap(nums,i,nums[i]-1);
}
for(int i=0;i<len+1;i++){
if(nums[i] != i+1){
return i+1;
}
}
return n+1;
}
//交换
public void swap(int[] nums,int i,int j){
int temp =nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}