力扣打卡(9):国庆第三天:排序要理解思想~ 不要胡思乱想··~~~

18 篇文章 0 订阅
16 篇文章 0 订阅

10.3lc

今天又是躺平的一天 。

国庆真是个结婚的好日子~~~ 我爸同事天天婚宴…

写了每日易题: 和几道排序 简单的回归一个 八大排序:

个人感觉:其实 主要的 插入 堆 快排 基数 希尔。

快排的复杂度:和分区点 有着很大的关系 建议最好还是 随计选择

先回顾一哈排序

a八大排序

1.冒泡排序

思想:依次进行比较选择最大的从后往前排,知道比较 arr.length-1次;

public static void bublerSorted(int[] arr){
    //领时交换变量;
    int temp=0;
    int length=arr.length;
    for(int i=0;i<leng-1;i++){
        //j<leng-1-i:每次循环比较后的 确定i位,所以会-i 比较剩下的位置的元素
        for(int j=0;j<leng-1-i;j++){
           if(arr[j]>arr[j+1]){
               temp=arr[j];
               arr[j]=arr[j+1];
               arr[j+1]=temp;
           }
        }
       System.out.println(Arrays.toString(arr));
    }
    
}
2.选择排序

思想:选择一个最小的:从前往后排:类似于 先排小 后排大:存的是索引的 所以速度比冒泡快一点:

因为在 内部的一次for循环中 数组存储的只是最小值和最小值的索引 所以少存一个值 快

public static void chooseSorted(int[] arr){
    for(int i=0;i<arr.length-1;i++){
        int minIndex=i;
        int min=arr[i];
        for(int j=i+1;j<arr.length-1,j++){
            if(min >arr[j]){
                min=arr[j];
                minIndex=j;
            }
            
            if(minIndex !=0){
                arr[minIndex]=arr[i];
                arr[i]=min;
            }
        }
        
    }
    System.out.println(Arrays.toString(arr));
} 
3.插入排序:

思想:每次都是最后一个数字 进行插入 其实位置 为 i-1; 类似起牌!

public static void insertSotred(int[] arr){
    int insertVal=0;
    int inserIndex=0;
    for(int i=0;i<arr.length-1;i++){
         insertVal=arr[i+1];
        inserIndex=i;
        while(insertIndex >= 0 &&arr[insertIndex]> insertVal){
            arr[insertIndex+1]=arr[insertIndex];
            insertIndex--;
        }
        
        arr[insertIndex+1] = insertVal;
    }
   System.out.println(Arrays.toString(arr));
}
public static void insertSotred(int[] arr){
   
    for(int i=0;i<arr.length-1;i++){
      for(int j=i-1;j>0&&arr[j]>arr[j+1];j--;)
          int temp=arr[j];
       	arr[j]=arr[j+1];
        arr[j+1]=temp;
    }
   System.out.println(Arrays.toString(arr));
}
4.希尔排序(交换)

思想:对于 插入排序的优化: 分组化进行 交换

public static void shellSorted(int[] arr){
    int temp=0;
    //临时中间变量
    for(int gap = arr.length/2;gap >= 0;gap /=2){
        //i<arr.lenth;要保证最后一位也能吃住:
        for(int i=gap;i<arr.lenth;i++){
             for(int j=i-gap; j>=0; j-=gap){
                 if(arr[j] > arr[j+gap]){
                     temp=arr[j];
                     arr[j]=arr[j+gap];
                     arr[j+gap]=temp;
                 }
             }
        }
    }
}
5.希尔排序(插排)快

思想:把原来基于交换的思想 转换位 插入!

public static void shellSorted(int[] arr){
    int temp=0;
    //临时中间变量
    for(int gap = arr.length/2;gap >= 0;gap /=2){
        //i<arr.lenth;要保证最后一位也能吃住:
        for(int i=gap;i<arr.lenth;i++){
            int j=i;
            int temp=arr[j]
            while( j-gap >=0 && arr[j] < arr[j-gap]){
                arr[j]=arr[j-gap];
                j -=gap;
            }    
              arr[j]=temp;  
             }
        }
    }
}
6.快速排序(重要)

: 顺序关系很重要!

从左边开始 就一定要从右边开始遍历 不然少一次遍历:

private static void quickSort(int[] arr, int left, int right) {
    if (left < right) {
        int partitionIndex = partition(arr, left, right);
        quickSort(arr, left, partitionIndex - 1);
        quickSort(arr, partitionIndex + 1, right);
    }
}

private static int partition(int[] arr, int left, int right) {
    int pivot = arr[left];
    //终止while循环以后left和right一定相等的
    while (left < right) {
        while (left < right && arr[right] >= pivot) {
            --right;
        }
        arr[left] = arr[right];
        while (left < right && arr[left] <= pivot) {
            ++left;
        }
        arr[right] = arr[left];
    }
    arr[left] = pivot;
    //right可以改为left
    return left;
}

第二种

    
    ublic static viod  sort(int[] arr,int left,int right){
   
  if(left>right){
        return;
    }
    int baseNumber=arr[left];
    int temp=0;
    //中间变量
    int l=left,r=right;
    while(l != r){
        while(arr[r]>=baseNumber && l < r){
            r--;
        }
         while(arr[l]<=baseNumber && l < r){
            l++;
        }
        if(l < r){
            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;
        }
        //准基数归位
        arr[left] = arr[l];
        arr[l] = baseNumber;
       sort(arr,left,l-1);
        sort(arr,l+1,right);
    }
}
public static void quickSort(int[] arr){    int len = arr.length;    if(len ==null ||len == 1 ||len == 0){        return;    }    sort(arr,0,len-1);}public static void  sort(int[] arr,int left, int right){    int  base= arr[left];    int l=left,r=right;    int temp=0;        if(left > right){        return;    }    while(l != r ){        while(l<r && arr[r] >= base){            r--;        }        while(l<r && arr[l] <=base){            l++;        }        if(l<r){            temp=arr[l];            arr[l]=arr[r];            arr[r] =temp;        }       arr[left]=arr[l];        arr[l]=base;               sort(arr,left,l-1);       sort(arr,l+1,right);    }}

7.基数排序

思想:分而治之

拆成最小快,排序后在进行合并

public static mergeSort(int[] arr,int left,int right,int[] temp){    int mid=(leth+right)/2;    int[] temp=new int[arr.length];     mergeSort(arr,left,mid,temp);     mergeSort(arr,mid+1,right,temp);    sort(arr,)}

三大查找

1.线性查找

思想:就是直接遍历搜索:

public static int search(int[] arr, int findValue){    for(int i=0;i<arr.length-1;i++){        if(arr[i] == finfValue){            return i;        }        return -1;    }}
2.二分查找:

思想:中间查找:注意一个数字问题

//注意:使用二分查找的前提是 该数组是有序的.public class BinarySearch {	public static void main(String[] args) {				int arr[] = { 1, 8, 10, 89, 1000, 1000, 1000, 1234 };		List<Integer> resIndexList = binarySearch(arr, 0, arr.length - 1, 1000);		System.out.println("resIndexList=" + resIndexList);			}	// 完成一个课后思考题:	/*	 * 课后思考题: {1,8, 10, 89, 1000, 1000,1234} 当一个有序数组中, 有多个相同的数值时,如何将所有的数值都查找到,比如这里的	 * 1000	 * 	 * 思路分析 1. 在找到mid 索引值,不要马上返回 2. 向mid 索引值的左边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList	 * 3. 向mid 索引值的右边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList 4. 将Arraylist返回	 */	public static List<Integer> binarySearch(int[] arr, int left, int right, int findVal) {				// 当 left > right 时,说明递归整个数组,但是没有找到		if (left > right) {			return new ArrayList<Integer>();		}		int mid = (left + right) / 2;		int midVal = arr[mid];		if (findVal > midVal) { // 向 右递归			return binarySearch(arr, mid + 1, right, findVal);		} else if (findVal < midVal) { // 向左递归			return binarySearch(arr, left, mid - 1, findVal);		} else {			// 思路分析			// 1. 在找到mid 索引值,不要马上返回			// 2. 向mid 索引值的左边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList			// 3. 向mid 索引值的右边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList			// 4. 将Arraylist返回			List<Integer> resIndexlist = new ArrayList<Integer>();			// 向mid 索引值的左边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList			int temp = mid - 1;			while (true) {				if (temp < 0 || arr[temp] != findVal) {// 退出					break;				}				// 否则,就temp 放入到 resIndexlist				resIndexlist.add(temp);				temp -= 1; // temp左移			}			resIndexlist.add(mid); //			// 向mid 索引值的右边扫描,将所有满足 1000, 的元素的下标,加入到集合ArrayList			temp = mid + 1;			while (true) {				if (temp > arr.length - 1 || arr[temp] != findVal) {// 退出					break;				}				// 否则,就temp 放入到 resIndexlist				resIndexlist.add(temp);				temp += 1; // temp右移			}			return resIndexlist;		}	}}

3.插值查找

思想:就是换了的mid的公式 来进行 查找:

int mid = low + (high - low) * (key - arr[low]) / (arr[high] - arr[low]) ;

public static int insertFind(int[] arr,int left,int right,int findValue){    int mid=left+(right-left)*(findValue-arr[left])/(arr[right]-arr[left]);  	int midVal = arr[mid];		if (findVal > midVal) { // 说明应该向右边递归			return insertValueSearch(arr, mid + 1, right, findVal);		} else if (findVal < midVal) { // 说明向左递归查找			return insertValueSearch(arr, left, mid - 1, findVal);		} else {			return mid;		}}

166. 分数到小数 - 力扣(LeetCode) (leetcode-cn.com)

:直接思路运算即可

class Solution {
    public String fractionToDecimal(int numerator, int denominator) {
         long a =numerator,b=denominator;
         if(a%b == 0) return String.valueOf(a/b);
         StringBuilder sb=new StringBuilder();
     // 判断符号  如果小  就是 一正一副 除为-
         if(a*b<0) sb.append('-');
//转为正数
         a=Math.abs(a); b=Math.abs(b);
        //拼接 小数点 前
         sb.append(String.valueOf(a/b)+'.');
        // 余数
         a%=b;
        Map<Long,Integer> map=new HashMap<>();
         while(a !=0){
             // map 存的是  key 循环值 value : 长度
             map.put(a,sb.length());
             a*=10;
             sb.append(a/b);
             a%=b;

             if(map.containsKey(a)){
                  int u =map.get(a);
                 //正则表达式的
                return String.format("%s(%s)",sb.substring(0,u),sb.substring(u));
             }
         }
         return sb.toString();
    }
}

628. 三个数的最大乘积 - 力扣(LeetCode) (leetcode-cn.com)

:直接Arrays.sort()~~~

:或者 线性扫描

class Solution {
    public int maximumProduct(int[] nums) {
         int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
        // 最大的、第二大的和第三大的
        int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE;

       for(int x:nums){
           if(x<min1){
               min2=min1;
               min1=x;
           }else  if(x<min2){
               min2=x;
           }

           if(x>max1){
               max3=max2;
               max2=max1;
               max1=x;
           }else if (x>max2){
               max3=max2;
               max2=x;
           }else  if(x>max3){
               max3=x;
           }

       }
       return Math.max((max1*max2*max3),(min1*min2*max1));
    }
}

88. 合并两个有序数组 - 力扣(LeetCode) (leetcode-cn.com)

:直接拼接

:或者 辅助数组 +双指针

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
     int i = m,j = 0;
        while(i < m + n){
            nums1[i++] = nums2[j++];
        }
        Arrays.sort(nums1);
}}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值