面试算法大全-数组总结

1、数组

1.1 一维数组

1.1.1遍历
public class Arraytest {
    public static void main(String[] args) {
        int[] arr={1,3,4,5,6,8,9};
        
        //顺序遍历
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]);
        }
        for (int a : arr) {
            System.out.print(a);
        }
        //逆序遍历
        for (int i = arr.length - 1; i >= 0; i--) {
            System.out.print(arr[i]);
        }
    }
}
1.1.2 最值
//最大值:
public static int getMax(int[] arr) {
    int max = arr[0];
    for(int x=1; x<arr.length; x++) {
        if(arr[x] > max) {
            max = arr[x];
        }
    }
    return max;
}
//最小值:
public static int getMin(int[] arr) {
    int min = arr[0];
    for (int x = 1; x < arr.length; x++) {
        if (arr[x] < min) {
            min = arr[x];
        }
    }
    return min;
}
1.1.3 逆序
//方式1:
public static void reverse1(int[] arr) {
    for(int x=0; x<arr.length/2; x++) {
        int temp = arr[x];
        arr[x] = arr[arr.length-1-x];
        arr[arr.length-1-x] = temp;
    }
}
//方式2:
public static void reverse2(int[] arr) {
    for(int start=0,end=arr.length-1; start<=end; start++,end--) {
        int temp = arr[start];
        arr[start] = arr[end];
        arr[end] = temp;
    }
}
1.1.4 基本查找
// 方式1:
 public static int getIndex1(int[] arr,int value) {
     for(int i=0; i<arr.length; i++) {
         if(arr[i] == value) {
             return i;
         }
     }
     return -1;
 }

 //方式2:
 public static int getIndex3(int[] arr,int value) {
     int index = -1;
     for(int i=0; i<arr.length; i++) {
         if(arr[i] == value) {
             index = i;
             break;
         }
     }
     return index;
 }
1.1.5 十大排序

在这里插入图片描述

1.1.5.1 冒泡排序
import java.util.Arrays;
public class BubbleSort {
    public static int[] bubbleSort(int[] arr){
        if (arr.length == 0) {
            return arr;
        }
        int length = arr.length;
        int temp;
        //第多少趟排序
        for (int i = 0; i < length-1; i++) {
            //第多少行排序
            for (int j = 0; j < length-i-1; j++) {
                if (arr[j]>arr[j+1]){
                    temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
        }
        return arr;
    }
    public static void main(String[] args) {
        int[] arr={8,5,6,1,4,3,9,2};
        int[] bubbleSort = BubbleSort.bubbleSort(arr);
        System.out.println(Arrays.toString(bubbleSort));
    }
}
1.1.5.2 选择排序
public class SelectionSort {
	public static int[] selectionSort(int[] arr) {
		if (arr.length == 0) {
			return arr;
		}
		int length = arr.length;
		int temp, minIndex;
		
		for(int i=0; i<length-1; i++) {
			minIndex = i;
			for(int j=i; j<length; j++) {
				if(arr[j] < arr[minIndex]) {
					minIndex = j;
				}
			}
			temp = arr[i];
			arr[i] = arr[minIndex];
			arr[minIndex] = temp;
		}
		return arr;
	}
	
	public static void main(String[] args) {
		int[] arr = {10,15,25,37,21,13,9,10,15,2};
		int[] sort = SelectionSort.selectionSort(arr);
		System.out.println(Arrays.toString(sort));
	}
}
1.1.5.3 插入排序
public class InsertionSort {
    public static int[] insertionSort(int[] array) {
        if (array.length == 0) {
            return array;
        }
        int length = array.length;
        int preIndex, current;

        for (int i = 1; i < length; i++) {
            preIndex = i - 1;
            current = array[i];
            
            while (preIndex >= 0 && array[preIndex] > current) {
                array[preIndex + 1] = array[preIndex];
                preIndex--;
            }
            array[preIndex + 1] = current;
        }
        return array;
    }
    
    public static void main(String[] args) {
        int[] arr = {10, 15, 25, 37, 21, 13, 9, 10, 15, 2};
        int[] sort = InsertionSort.insertionSort(arr);
        System.out.println(Arrays.toString(sort));
    }
}
1.1.5.4 希尔排序
public class ShellSort {
	public static int[] shellSort(int[] array) {
		if (array.length == 0) {
			return array;
		}
        
		int len = array.length;
		int temp, gap = len / 2;
        
		while (gap > 0) {
			for (int i = gap; i < len; i++) {
				temp = array[i];
				int preIndex = i - gap;
				while (preIndex >= 0 && array[preIndex] > temp) {
					array[preIndex + gap] = array[preIndex];
					preIndex -= gap;
				}
				array[preIndex + gap] = temp;
			}
			gap /= 2;
		}
		return array;
	}
	
	public static void main(String[] args) {
		int[] arr = {10,15,25,37,21,13,9,10,15,2};
		int[] sort = ShellSort.shellSort(arr);
		System.out.println(Arrays.toString(sort));
	}
}
1.1.5.5 归并排序
public class MergeSort {
	/**
	 *  两路归并算法,两个排好序的子序列合并为一个子序列
	 * @Title: merge
	 * @Description: 合并
	 * @param @param arr
	 * @param @param low
	 * @param @param mid
	 * @param @param high    参数
	 * @return void    返回类型
	 * @throws
	 */
	public static void merge(int[] arr, int low, int mid, int high) {
		int[] temp = new int[high-low+1];	//新数组
		int i = low;	//左指针
		int j = mid + 1;	//右指针
		int index = 0;	//临时变量,用于计算数组下标
		
		while(i<=mid && j<=high) {	//把较小的数先移到新数组中
			if(arr[i] < arr[j]) {
				temp[index++] = arr[i++];
			} else {
				temp[index++] = arr[j++];
			}
		}
		while(i <= mid) {	//把左边剩余数移入数组
			temp[index++] = arr[i++];
		}
		while(j <= high) {	//把右边剩余数移入数组
			temp[index++] = arr[j++];
		}
		for(int k=0; k<temp.length; k++) {	//把新数组中的数覆盖原数组
			arr[k+low] = temp[k];
		}
	}
	/**
	 * 
	 * @Title: mergeSort
	 * @Description: 合并排序
	 * @param @param arr
	 * @param @param low
	 * @param @param high    参数
	 * @return void    返回类型
	 * @throws
	 */
	public static int[] mergeSort(int[] arr, int low, int high) {
		if (arr.length == 0) {
			return arr;
		}
		int mid = ((high - low) >> 1) + low;
		if(low < high) {
			mergeSort(arr, low, mid);	//左边
			mergeSort(arr, mid+1, high);	//右边
			merge(arr, low, mid, high);	//左右合并
		}
		return arr;
	}
	/**
	 * 
	 * @Title: main
	 * @Description: 主函数——测试函数
	 * @param @param args    参数
	 * @return void    返回类型
	 * @throws
	 */
    public static void main(String[] args) {
        int a[] = { 51, 46, 20, 18, 65, 97, 82, 30, 77, 50 };
		int[] sort = mergeSort(a, 0, a.length - 1);
		for(int arr : sort) {
        	System.out.print(arr + " ");
        }
    }
}

第二种实现方法

public class Main {
	public static void main(String[] args) {
		int[] arr = {11,44,23,67,88,65,34,48,9,12};
		int[] tmp = new int[arr.length];    //新建一个临时数组存放
		mergeSort(arr,0,arr.length-1,tmp);
		for(int i=0;i<arr.length;i++){
			System.out.print(arr[i]+" ");
		}
	}
	
	public static void merge(int[] arr,int low,int mid,int high,int[] tmp){
		int i = 0;
		int j = low,k = mid+1;  //左边序列和右边序列起始索引
		while(j <= mid && k <= high){
			if(arr[j] < arr[k]){
				tmp[i++] = arr[j++];
			}else{
				tmp[i++] = arr[k++];
			}
		}
		//若左边序列还有剩余,则将其全部拷贝进tmp[]中
		while(j <= mid){    
			tmp[i++] = arr[j++];
		}
		while(k <= high){
			tmp[i++] = arr[k++];
		}
		for(int t=0;t<i;t++){
			arr[low+t] = tmp[t];
		}
	}
	public static void mergeSort(int[] arr,int low,int high,int[] tmp){
		if(low<high){
			int mid = (low+high)/2;
			mergeSort(arr,low,mid,tmp); //对左边序列进行归并排序
			mergeSort(arr,mid+1,high,tmp);  //对右边序列进行归并排序
			merge(arr,low,mid,high,tmp);    //合并两个有序序列
		}
	}
}
1.1.5.6 快速排序
public class QuickSortClass {
    /**
     * @param arr        待排序列
     * @param leftIndex  待排序列起始位置
     * @param rightIndex 待排序列结束位置
     */
    private static void quickSort(int[] arr, int leftIndex, int rightIndex) {
        if (leftIndex >= rightIndex) {
            return;
        }
        int left = leftIndex;
        int right = rightIndex;
        //待排序的第一个元素作为基准值
        int key = arr[left];

        //从左右两边交替扫描,直到left = right
        while (left < right) {
            while (right > left && arr[right] >= key) {
                //从右往左扫描,找到第一个比基准值小的元素
                right--;
            }

            //找到这种元素将arr[right]放入arr[left]中
            arr[left] = arr[right];

            while (left < right && arr[left] <= key) {
                //从左往右扫描,找到第一个比基准值大的元素
                left++;
            }

            //找到这种元素将arr[left]放入arr[right]中
            arr[right] = arr[left];
        }
        //基准值归位
        arr[left] = key;
        //对基准值左边的元素进行递归排序
        quickSort(arr, leftIndex, left - 1);
        //对基准值右边的元素进行递归排序。
        quickSort(arr, right + 1, rightIndex);
    }
    public static void main(String[] args) {
        int[] arr = {5, 1, 7, 3, 1, 6, 9, 4};

        quickSort(arr, 0, arr.length - 1);

        for (int i : arr) {
            System.out.print(i + "\t");
        }
    }
}

第二种写法

public class QuickSort {
	public static int[] quickSort(int[] array, int start, int end) {
		if (array.length < 1 || start < 0 || end >= array.length || start >= end) {
			return null;
		}
		//进行第一轮排序获取分割点
		int index = partition(array, start, end);
		//排序前半部分
		quickSort(array, start, index-1);
		//排序后半部分
		quickSort(array, index+1, end);
		return array;
	}
	
	/**
	 * 一次快速排序
	 * @param array
	 * @param lo
	 * @param hi
	 * @return key的下标index,也就是分片的间隔点
	 */
	public static int partition(int[] array, int lo, int hi) {
		int key = array[lo];
		while(lo<hi) {
			//从后半部分向前扫描
			while(array[hi]>=key && hi>lo) {
				hi--;
			}
			array[lo] = array[hi];
			//从前半部分向后扫描
			while(array[lo]<=key && hi>lo) {
				lo++;
			}
			array[hi] = array[lo];
		}
		array[hi] = key;	//存入基准
		return hi;
	}
	
	//测试
	public static void main(String[] args) {
	    int[] arr = {1,9,3,12,7,8,3,4,65,22};
		int[] sort = quickSort(arr, 0, arr.length - 1);
		System.out.println(Arrays.toString(sort));
	}
}

第三种写法

import java.util.Arrays;
import java.util.Random;

/**
 * 快速排序,使得整数数组 arr 有序
 */
public class QuickSortSwap {
    public static int[] quickSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return arr;
        }
        quickSort(arr, 0, arr.length - 1);
        return arr;
    }
    /**
     * 快速排序,使得整数数组 arr 的 [L, R] 部分有序
     */
    public static void quickSort(int[] arr, int L, int R) {
        if (L < R) {
            // 把数组中随机的一个元素与最后一个元素交换,这样以最后一个元素作为基准值实际上就是以数组中随机的一个元素作为基准值
            swap(arr, new Random().nextInt(R - L + 1) + L, R);
            int[] p = partition(arr, L, R);
            quickSort(arr, L, p[0] - 1);
            quickSort(arr, p[1] + 1, R);
        }
    }
    /**
     * 分区的过程,整数数组 arr 的[L, R]部分上,使得:
     * 大于 arr[R] 的元素位于[L, R]部分的右边,但这部分数据不一定有序
     * 小于 arr[R] 的元素位于[L, R]部分的左边,但这部分数据不一定有序
     * 等于 arr[R] 的元素位于[L, R]部分的中间
     * 返回等于部分的第一个元素的下标和最后一个下标组成的整数数组
     */
    public static int[] partition(int[] arr, int L, int R) {
        int basic = arr[R];
        int less = L - 1;
        int more = R + 1;
        while (L < more) {
            if (arr[L] < basic) {
                swap(arr, ++less, L++);
            } else if (arr[L] > basic) {
                swap(arr, --more, L);
            } else {
                L++;
            }
        }
        return new int[]{less + 1, more - 1};
    }
    /**
     * 交换数组 arr 中下标为 i 和下标为 j 位置的元素
     */
    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    public static void main(String[] args) {
        int[] arr = {1,9,3,12,7,8,3,4,65,22};
        int[] sort = QuickSortSwap.quickSort(arr);
        System.out.println(Arrays.toString(sort));
    }
}
1.1.5.7 堆排序
public class HeapSort {
	public static int[] heapSort(int[] array) {
		for(int i=array.length/2-1; i>=0; i--) {	//构建一个大顶堆
			adjustHeap(array, i, array.length-1);
		}
		for(int i=array.length-1; i>=0; i--) {	//将堆顶记录和当前未经排序子序列的最后一个记录交换
			int temp = array[0];
			array[0] = array[i];
			array[i] = temp;
			adjustHeap(array, 0, i-1);
		}
		return array;
	}

	//构造大根堆
	public static void adjustHeap(int[] array, int parent, int length) {
		int temp = array[parent];
		for(int child=2*parent; child<length; child*=2) {
			// 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点 
			if(child<length && array[child]<array[child+1]) {
				++child;
			}
			// 如果父结点的值已经大于孩子结点的值,则直接结束
			if(temp >= array[child]) {
				break;
			}
			array[parent] = array[child];
			parent = child;
		}
		array[parent] = temp;
	}
	
	//测试
	public static void main(String[] args) {
	    int[] arr = {1,9,3,12,7,8,3,4,65,22};
		int[] sort = HeapSort.heapSort(arr);
		System.out.println(Arrays.toString(sort));
	}
}
1.1.5.8 计数排序
public class CountingSort {
	public static int[] countingSort(int[] array) {
		if (array.length == 0) {
			return array;
		}
		int min = Integer.MAX_VALUE;
		int max = Integer.MIN_VALUE;
		for (int i=0; i<array.length; i++) {
			if (array[i] < min) {
				min = array[i];
				continue;
			}
			if (array[i] > max) {
				max = array[i];
			}
		}
		int[] countArray = new int[max-min+1];
		for (int i=0; i<array.length; i++) {
			countArray[array[i]-min] ++;
		}
		int k = 0;
		for (int i=0; i<countArray.length; i++) {
			for (int j=0; j<countArray[i]; j++) {
				array[k++] = min + i;
			}
		}
		return array;
	}
	//测试
	public static void main(String[] args) throws Exception {
	    int[] arr = {1,3,3,12,-7,8,8,4,65,-22, 8};
		int[] sort = CountingSort.countingSort(arr);
		System.out.println(Arrays.toString(sort));
	}
}
1.1.5.9 桶排序
public class BucketSort {
	public static int[] bucketSort(int[] arr){
	    int max = Integer.MIN_VALUE;
	    int min = Integer.MAX_VALUE;
	    for(int i = 0; i < arr.length; i++){
	        max = Math.max(max, arr[i]);
	        min = Math.min(min, arr[i]);
	    }
	    //桶数
	    int bucketNum = (max - min) / arr.length + 1;
	    ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);
	    for(int i = 0; i < bucketNum; i++){
	        bucketArr.add(new ArrayList<Integer>());
	    }
	    //将每个元素放入桶
	    for(int i = 0; i < arr.length; i++){
	        int num = (arr[i] - min) / (arr.length);
	        bucketArr.get(num).add(arr[i]);
	    }
		// 对每个桶进行排序
		for(int i = 0; i < bucketArr.size(); i++){
			Collections.sort(bucketArr.get(i));
		}
		// 将桶中的元素赋值到原序列
	    int k = 0;
	    for(int i = 0; i < bucketArr.size(); i++){
			// 对每个桶进行排序
	       // Collections.sort(bucketArr.get(i));
	        for(int j=0; j<bucketArr.get(i).size(); j++) {
	        	arr[k++] = bucketArr.get(i).get(j);
	        }
	    }
	    return arr;
	}
	public static void main(String[] args) {
		int[] arr = {10,15,25,37,21,13,9,10,15,2};
		int[] sort = BucketSort.bucketSort(arr);
		System.out.println(Arrays.toString(sort));
	}
}
1.1.5.10 基数排序
public class RadixSort {
	public static int[] radixSort(int[] arr, int d) {	//d为桶数(10进制范围0~9即10个桶)
		int max = arr[0];
		for (int i=0; i<arr.length; i++) {	//找出数组中的最大值
			max = Math.max(max, arr[i]);
		}
		int key = 0;	//数组中关键字的个数(以个位、十位、百位……为关键字,最大值的位数就是关键字的个数)
		while (max > 0) {
			max /= 10;
			key ++;
		}
		List<ArrayList<Integer>> buckets = new ArrayList<>();
		for (int i=0; i<d; i++) {
			buckets.add(new ArrayList<>());
		}
		for (int i=0; i<key; i++) {		//由个位开始,依次按关键字进行分配
			for (int j=0; j<arr.length; j++) {	//扫描所有元素,将其分配到桶
				int index = arr[j] % (int)Math.pow(10, i+1) / (int)Math.pow(10, i);		//取出个位、十位、百位……的数字
				buckets.get(index).add(arr[j]);
			}
			//分配完成,将桶中元素复制回原数组
			int counter = 0;
			for (int j=0; j<10; j++) {
				ArrayList<Integer> bucket = buckets.get(j);	//关键字为j的桶
				while (bucket.size() > 0) {
					arr[counter++] = bucket.remove(0);
				}
			}
		}
		return arr;
	}
	//测试
	public static void main(String[] args) {
	    int[] arr = {1,9,3,12,7,8,3,4,65,22};
		int[] sort = RadixSort.radixSort(arr, 10);
		System.out.println(Arrays.toString(sort));
	}
}

1.2 二维数组

1.2.1 遍历
//第一种形式
public static void traversal(int[][] array){
    //遍历行
    for(int i=0;i<array.length;i++)
    {
        //遍历列
        for(int j=0;j<array[i].length;j++)//利用嵌套for循环来遍历二维数组
        {
            System.out.println(array[i][j]);
        }
    }
}

//第二种形式
public static void traversal2(int[][] array){
    for (int[] arr : array) {
        for (int a : arr) {
            System.out.println(a);
        }
    }
}

1.2.2 求和
public static int add(int[][] arr)//求和子函数
{
    int sum=0;
    for(int i=0;i<arr.length;i++)
    {
        for(int j=0;j<arr[i].length;j++)//利用嵌套for循环来遍历二维数组
        {
            sum+=arr[i][j];//每遍历出一个元素则叠加一次
        }
    }
    return sum;//返回二维数组中个元素的和
}
1.2.3 均值
public static void average(int[][] arr)//求平均值 
{ 
    for(int i=0;i<arr.length;i++) 
    { 
        int sum=0; 
        for(int j=0;j<arr[i].length;j++) 
        { 
            sum=sum+arr[i][j]; 
        } 
        int average=sum/3; 
        System.out.println(average); 
    } 
} 
1.2.4 最值
//获取最大值
public static void getMax(int[][] arr)
{ 
    for(int i=0;i<arr.length;i++) 
    { 
        int max=arr[i][0]; 
        for(int j=1;j<arr[i].length;j++) 
        { 
            if(arr[i][j]>max) 
            { 
                max=arr[i][j]; 
            } 
        } 
        System.out.println(max); 
    } 
} 
//获取最小值
public static void getMin(int[][] arr)
{ 
    for(int i=0;i<arr.length;i++) 
    { 
        int min=arr[i][0]; 
        for(int j=1;j<arr[i].length;j++) 
        { 
            if(arr[i][j]<min) 
            { 
                min=arr[i][j]; 
            } 
        } 
        System.out.println(min); 
    } 
} 
1.2.5查找
//暴力查找
public boolean Find(int target, int [][] array) {
        if(array.length == 0)// 如果二维数组为空,直接返回false
        {
            return false;
        }
        for(int i=0;i<array.length;i++) {
            for(int j=0;j<array[i].length;j++){
                if(array[i][j] == target ) {
                    return true;
                }
            }
        }
        return false;
    }
}
// 第二种 时间复杂度 O(M+N) 空间复杂度O(1)
public static boolean Find2(int target, int[][] array) {
    if(array.length == 0)// 如果二维数组为空,直接返回false
    {
        return false;
    }
    int row=0;  //第0行
    int col=array[0].length-1; //第1行长度减1就是最后1列
    int rowNumber=array.length;//总行数
    while (row<rowNumber&&col>=0){
        if (array[row][col]>target){
            col--;
        }
        else if (array[row][col]<target){
            row++;
        }
        else {
            return true;
        }
    }
    return false;
}
1.2.6 对角线遍历

img

//对角线遍历
public static int[] findDiagonalOrder(int[][] matrix) {
    int[] a=new int[0];
    if (matrix.length==0) {
        return a;
    }
    int m = matrix.length;
    int n = matrix[0].length;
    int j=0;
    int[] nums =new int[m*n];
    boolean bXFlag = true;
    for (int i = 0; i < m + n; i++) // 1. 坐标(x, y)相加的和是递增的
    {
        // 2. 逻辑处理是一样的,x,y的上限值是相反的
        int pm = bXFlag ? m : n;
        int pn = bXFlag ? n : m;
        int x = (i < pm) ? i : pm - 1; // 3. 例如这一趟是 x 从大到小, x 尽量取最大
        int y = i - x;                 // 3. 当初始值超过 x 的上限时,不足的部分加到 y 上面
        while (x >= 0 && y < pn) // 4. 这一趟结束的判断是, x 减到 0 或者 y 加到上限
        {
            // 5. 方向相反时,x,y是相反的
            nums[j]=bXFlag ? matrix[x][y] : matrix[y][x];
            j++;
            x--; // 2. 每一趟都是 x 或 y 其中一个从大到小(每次-1)
            y++; // 2. 另一个从小到大(每次+1)
        }
        // 5. 循环进行
        bXFlag = !bXFlag;
    }
    return nums;
}
1.2.7 旋转90度
   public void rotate(int[][] matrix) {
        int N = matrix.length;
        for (int i = 0; i < N/2; i++) {
            for (int j = 0; j < (N+1)/2; j++) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[N-1-j][i];
                matrix[N-1-j][i] = matrix[N-1-i][N-1-j];
                matrix[N-1-i][N-1-j] = matrix[j][N-1-i];
                matrix[j][N-1-i] = temp;
            }
        }
    }

//N*N型矩阵旋转90°相当于矩阵上下对折再沿对角线对折
public void rotate(int[][] matrix) {
        int size = matrix.length;
        for (int row = 0; row < size / 2; row++) {
            for (int col = 0; col < size; col++) {
                int temp = matrix[row][col];
                matrix[row][col] = matrix[size - row - 1][col];
                matrix[size - row - 1][col] = temp;
            }
        }
        for(int row = 0 ; row < size ; row++){
            for(int col = 0 ; col < row+1 ; col ++){
                int temp = matrix[row][col];
                matrix[row][col] = matrix[col][row];
                matrix[col][row] = temp;
            }
        }
    }
1.2.8 螺旋打印(顺时针或者逆时针)

img

    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> list = new ArrayList<>();
        //这里记住不要先设置变量,然后通过变量来判断长度是否为0,
        //因为如果为空的时候,是得不到宽度的,会报错
        if (matrix.length == 0 || matrix == null || matrix[0].length == 0) {
            return list;
        }
        int len = matrix.length;
        int widlen = matrix[0].length;
        for (int i = 0; i < (Math.min(len, widlen) + 1) / 2; i++) {
            for (int j = i; j < widlen - i; j++) {
                list.add(matrix[i][j]);
            }
            for (int j = i + 1; j < len - i; j++) {
                list.add(matrix[j][widlen - i - 1]);
            }
            for (int j = widlen - i - 2; j >= i; j--) {
                //防止出现重复遍历的情况
                if (list.size() == len * widlen) {
                    break;
                }
                list.add(matrix[len - i - 1][j]);
            }
            for (int j = len - i - 2; j > i; j--) {
                //防止出现重复遍历的情况
                if (list.size() == len * widlen) {
                    break;
                }
                list.add(matrix[j][i]);
            }
        }
        return list;
    }

1.3 经典题目源码

转置矩阵
class Solution {
    public int[][] transpose(int[][] A) {
        int R = A.length, C = A[0].length;
        int[][] ans = new int[C][R];
        for (int r = 0; r < R; ++r)
            for (int c = 0; c < C; ++c) {
                ans[c][r] = A[r][c];
            }
        return ans;
    }
}
寻找两个正序数组的中位数
class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int length1 = nums1.length, length2 = nums2.length;
        int totalLength = length1 + length2;
        if (totalLength % 2 == 1) {
            int midIndex = totalLength / 2;
            double median = getKthElement(nums1, nums2, midIndex + 1);
            return median;
        } else {
            int midIndex1 = totalLength / 2 - 1, midIndex2 = totalLength / 2;
            double median = (getKthElement(nums1, nums2, midIndex1 + 1) + getKthElement(nums1, nums2, midIndex2 + 1)) / 2.0;
            return median;
        }
    }

    public int getKthElement(int[] nums1, int[] nums2, int k) {
        /* 主要思路:要找到第 k (k>1) 小的元素,那么就取 pivot1 = nums1[k/2-1] 和 pivot2 = nums2[k/2-1] 进行比较
         * 这里的 "/" 表示整除
         * nums1 中小于等于 pivot1 的元素有 nums1[0 .. k/2-2] 共计 k/2-1 个
         * nums2 中小于等于 pivot2 的元素有 nums2[0 .. k/2-2] 共计 k/2-1 个
         * 取 pivot = min(pivot1, pivot2),两个数组中小于等于 pivot 的元素共计不会超过 (k/2-1) + (k/2-1) <= k-2 个
         * 这样 pivot 本身最大也只能是第 k-1 小的元素
         * 如果 pivot = pivot1,那么 nums1[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums1 数组
         * 如果 pivot = pivot2,那么 nums2[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums2 数组
         * 由于我们 "删除" 了一些元素(这些元素都比第 k 小的元素要小),因此需要修改 k 的值,减去删除的数的个数
         */

        int length1 = nums1.length, length2 = nums2.length;
        int index1 = 0, index2 = 0;
        int kthElement = 0;

        while (true) {
            // 边界情况
            if (index1 == length1) {
                return nums2[index2 + k - 1];
            }
            if (index2 == length2) {
                return nums1[index1 + k - 1];
            }
            if (k == 1) {
                return Math.min(nums1[index1], nums2[index2]);
            }
            // 正常情况
            int half = k / 2;
            int newIndex1 = Math.min(index1 + half, length1) - 1;
            int newIndex2 = Math.min(index2 + half, length2) - 1;
            int pivot1 = nums1[newIndex1], pivot2 = nums2[newIndex2];
            if (pivot1 <= pivot2) {
                k -= (newIndex1 - index1 + 1);
                index1 = newIndex1 + 1;
            } else {
                k -= (newIndex2 - index2 + 1);
                index2 = newIndex2 + 1;
            }
        }
    }
}
直方图的水量

方法一:双指针

class Solution {
    public int trap(int[] height) {
        if(height.length < 3) return 0;

        int left = 0, right = height.length - 1;
        int leftmax = height[left], rightmax = height[right];
        int res = 0;

        while(left < right){
            if(leftmax < rightmax){
                res += leftmax - height[left++];
                leftmax = Math.max(height[left], leftmax);
            }else{
                res += rightmax - height[right--];
                rightmax = Math.max(height[right], rightmax);
            }
        }
        return res;
    }
}

方法二:

class Solution {
    private int[] height;

    public int trap(int[] height) {
    	if(height.length <= 2)
    		return 0;
    	this.height = height;
        int sum = 0;
        int start = 0, end = 0;
        for(int i = 0; i < height.length; ++i) {  //初次遍历,找到最高的柱子给到start,end
        	if(height[start] < height[i]) {
        		start = i;
        		end = i;
        	}
        }
        while(start > 0 || end < height.length-1){
		//除start到end之外,找到最高柱子的位置 p,h[p] <=h[start] 并且h[p]<=h[end]
            int p = findHighest(start,end);
            if(start > p) {    //p在start前面时,计算此时p到start之间的积水
            	for(int i = h+1; i < start; ++i) {
            		sum += height[p]-height[i];
            	}
            	start = p;
            }
            if(end < p) {     //p在end后面时,计算此时end到p之间的积水
            	for(int i = end+1; i < p; ++i) {
            		sum += height[p]-height[i];
            	}
            	end = p;
            }
        }
        return sum;
    }
	//这个方法的作用是找到 start到end之外(不包含自身)的最高的h[i],返回i
    private int findHighest(int start, int end){
    	int p = -1, max = -1;
    	for(int i = 0; i < start; ++i) {
    		if(max < height[i]) {
    			max = height[i];
    			p = i;
    		}
    	}
    	for(int i = end+1; i < height.length; ++i) {
    		if(max < height[i]) {
    			max = height[i];
    			p = i;
    		}
    	}
        return p;
    }
}
绝对差不超过限制的最长连续子数组
class Solution {
    public int longestSubarray(int[] nums, int limit) {
        // 两个单调队列分别维护从left到right之间的最大值最小值
        Deque<Integer> minDeque = new LinkedList<>();
        Deque<Integer> maxDeque = new LinkedList<>();
        int result = 0;
        int left = 0, right = 0;
        minDeque.offer(0);
        maxDeque.offer(0);
        while (right < nums.length) {
            int minIdx = minDeque.peekFirst();
            int maxIdx = maxDeque.peekFirst();
            if (nums[maxIdx] - nums[minIdx] <= limit) {
                // 最大值与最小值之差小于等于限制的情况下右指针右移
                result = Math.max(result, right - left + 1);
                ++right;
                // 维护两个单调队列
                while (right < nums.length && minDeque.size() > 0 && nums[right] < nums[minDeque.peekLast()]) {
                    minDeque.pollLast();
                }
                minDeque.offerLast(right);
                while (right < nums.length && maxDeque.size() > 0 && nums[right] > nums[maxDeque.peekLast()]) {
                    maxDeque.pollLast();
                }
                maxDeque.offerLast(right);
            }
            else {
                // 最大值与最小值之差大于限制的情况下左指针右移
                left = Math.min(minIdx, maxIdx) + 1;
                while (minDeque.size() > 0 && minDeque.peekFirst() < left) {
                    minDeque.pollFirst();
                }
                while (maxDeque.size() > 0 && maxDeque.peekFirst() < left) {
                    maxDeque.pollFirst();
                }
            }
        }
        return result;
    }
}
三角形最小路径和

方法一:动态规划

class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        int n = triangle.size();
        int[][] f = new int[n][n];
        f[0][0] = triangle.get(0).get(0);
        for (int i = 1; i < n; ++i) {
            f[i][0] = f[i - 1][0] + triangle.get(i).get(0);
            for (int j = 1; j < i; ++j) {
                f[i][j] = Math.min(f[i - 1][j - 1], f[i - 1][j]) + triangle.get(i).get(j);
            }
            f[i][i] = f[i - 1][i - 1] + triangle.get(i).get(i);
        }
        int minTotal = f[n - 1][0];
        for (int i = 1; i < n; ++i) {
            minTotal = Math.min(minTotal, f[n - 1][i]);
        }
        return minTotal;
    }
}

方法二:动态规划 + 空间优化

class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        int n = triangle.size();
        int[][] f = new int[2][n];
        f[0][0] = triangle.get(0).get(0);
        for (int i = 1; i < n; ++i) {
            int curr = i % 2;
            int prev = 1 - curr;
            f[curr][0] = f[prev][0] + triangle.get(i).get(0);
            for (int j = 1; j < i; ++j) {
                f[curr][j] = Math.min(f[prev][j - 1], f[prev][j]) + triangle.get(i).get(j);
            }
            f[curr][i] = f[prev][i - 1] + triangle.get(i).get(i);
        }
        int minTotal = f[(n - 1) % 2][0];
        for (int i = 1; i < n; ++i) {
            minTotal = Math.min(minTotal, f[(n - 1) % 2][i]);
        }
        return minTotal;
    }
}
class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        int n = triangle.size();
        int[] f = new int[n];
        f[0] = triangle.get(0).get(0);
        for (int i = 1; i < n; ++i) {
            f[i] = f[i - 1] + triangle.get(i).get(i);
            for (int j = i - 1; j > 0; --j) {
                f[j] = Math.min(f[j - 1], f[j]) + triangle.get(i).get(j);
            }
            f[0] += triangle.get(i).get(0);
        }
        int minTotal = f[0];
        for (int i = 1; i < n; ++i) {
            minTotal = Math.min(minTotal, f[i]);
        }
        return minTotal;
    }
}
合并两个有序数组

双指针

// 从前往后
class Solution {
  public void merge(int[] nums1, int m, int[] nums2, int n) {
    // Make a copy of nums1.
    int [] nums1_copy = new int[m];
    System.arraycopy(nums1, 0, nums1_copy, 0, m);

    // Two get pointers for nums1_copy and nums2.
    int p1 = 0;
    int p2 = 0;

    // Set pointer for nums1
    int p = 0;

    // Compare elements from nums1_copy and nums2
    // and add the smallest one into nums1.
    while ((p1 < m) && (p2 < n))
      nums1[p++] = (nums1_copy[p1] < nums2[p2]) ? nums1_copy[p1++] : nums2[p2++];

    // if there are still elements to add
    if (p1 < m)
      System.arraycopy(nums1_copy, p1, nums1, p1 + p2, m + n - p1 - p2);
    if (p2 < n)
      System.arraycopy(nums2, p2, nums1, p1 + p2, m + n - p1 - p2);
  }
}

//从后往前
class Solution {
  public void merge(int[] nums1, int m, int[] nums2, int n) {
    // two get pointers for nums1 and nums2
    int p1 = m - 1;
    int p2 = n - 1;
    // set pointer for nums1
    int p = m + n - 1;

    // while there are still elements to compare
    while ((p1 >= 0) && (p2 >= 0))
      // compare two elements from nums1 and nums2 
      // and add the largest one in nums1 
      nums1[p--] = (nums1[p1] < nums2[p2]) ? nums2[p2--] : nums1[p1--];

    // add missing elements from nums2
    System.arraycopy(nums2, 0, nums1, 0, p2 + 1);
  }
}
长度最小的子数组
class Solution {
    public int minSubArrayLen(int s, int[] nums) {
        int n = nums.length;
        if (n == 0) {
            return 0;
        }
        int ans = Integer.MAX_VALUE;
        int start = 0, end = 0;
        int sum = 0;
        while (end < n) {
            sum += nums[end];
            while (sum >= s) {
                ans = Math.min(ans, end - start + 1);
                sum -= nums[start];
                start++;
            }
            end++;
        }
        return ans == Integer.MAX_VALUE ? 0 : ans;
    }
}
二维数组中的查找

方法一:暴力

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return false;
        }
        int rows = matrix.length, columns = matrix[0].length;
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < columns; j++) {
                if (matrix[i][j] == target) {
                    return true;
                }
            }
        }
        return false;
    }
}

方法二:线性查找

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return false;
        }
        int rows = matrix.length, columns = matrix[0].length;
        int row = 0, column = columns - 1;
        while (row < rows && column >= 0) {
            int num = matrix[row][column];
            if (num == target) {
                return true;
            } else if (num > target) {
                column--;
            } else {
                row++;
            }
        }
        return false;
    }
}
搜索二维矩阵
class Solution {
  public boolean searchMatrix(int[][] matrix, int target) {
    int m = matrix.length;
    if (m == 0) return false;
    int n = matrix[0].length;

    // 二分查找
    int left = 0, right = m * n - 1;
    int pivotIdx, pivotElement;
    while (left <= right) {
      pivotIdx = (left + right) / 2;
      pivotElement = matrix[pivotIdx / n][pivotIdx % n];
      if (target == pivotElement) return true;
      else {
        if (target < pivotElement) right = pivotIdx - 1;
        else left = pivotIdx + 1;
      }
    }
    return false;
  }
}
斐波那契数

方法一:递归

public class Solution {
    public int fib(int N) {
        if (N <= 1) {
            return N;
        }
        return fib(N-1) + fib(N-2);
    }
}

方法二:记忆化自底向上的方法

class Solution {
    public int fib(int N) {
        if (N <= 1) {
            return N;
        }
        return memoize(N);
    }

    public int memoize(int N) {
      int[] cache = new int[N + 1];
      cache[1] = 1;

      for (int i = 2; i <= N; i++) {
          cache[i] = cache[i-1] + cache[i-2];
      }
      return cache[N];
    }
}

方法三:记忆化自顶向下的方法

class Solution {
    private Integer[] cache = new Integer[31];

    public int fib(int N) {
        if (N <= 1) {
            return N;
        }
        cache[0] = 0;
        cache[1] = 1;
        return memoize(N);
    }

    public int memoize(int N) {
      if (cache[N] != null) {
          return cache[N];
      }
      cache[N] = memoize(N-1) + memoize(N-2);
      return memoize(N);
    }
}

方法四:自底向上进行迭代

class Solution {
    public int fib(int N) {
        if (N <= 1) {
            return N;
        }
        if (N == 2) {
            return 1;
        }

        int current = 0;
        int prev1 = 1;
        int prev2 = 1;

        for (int i = 3; i <= N; i++) {
            current = prev1 + prev2;
            prev2 = prev1;
            prev1 = current;
        }
        return current;
    }
}
子集

方法一:迭代法实现子集枚举

class Solution {
    List<Integer> t = new ArrayList<Integer>();
    List<List<Integer>> ans = new ArrayList<List<Integer>>();

    public List<List<Integer>> subsets(int[] nums) {
        int n = nums.length;
        for (int mask = 0; mask < (1 << n); ++mask) {
            t.clear();
            for (int i = 0; i < n; ++i) {
                if ((mask & (1 << i)) != 0) {
                    t.add(nums[i]);
                }
            }
            ans.add(new ArrayList<Integer>(t));
        }
        return ans;
    }
}

方法二:递归法实现子集枚举

class Solution {
    List<Integer> t = new ArrayList<Integer>();
    List<List<Integer>> ans = new ArrayList<List<Integer>>();

    public List<List<Integer>> subsets(int[] nums) {
        dfs(0, nums);
        return ans;
    }

    public void dfs(int cur, int[] nums) {
        if (cur == nums.length) {
            ans.add(new ArrayList<Integer>(t));
            return;
        }
        t.add(nums[cur]);
        dfs(cur + 1, nums);
        t.remove(t.size() - 1);
        dfs(cur + 1, nums);
    }
}
最短无序连续子数组

方法 1:暴力

public class Solution {
    public int findUnsortedSubarray(int[] nums) {
        int res = nums.length;
        for (int i = 0; i < nums.length; i++) {
            for (int j = i; j <= nums.length; j++) {
                int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE, prev = Integer.MIN_VALUE;
                for (int k = i; k < j; k++) {
                    min = Math.min(min, nums[k]);
                    max = Math.max(max, nums[k]);
                }
                if ((i > 0 && nums[i - 1] > min) || (j < nums.length && nums[j] < max))
                    continue;
                int k = 0;
                while (k < i && prev <= nums[k]) {
                    prev = nums[k];
                    k++;
                }
                if (k != i)
                    continue;
                k = j;
                while (k < nums.length && prev <= nums[k]) {
                    prev = nums[k];
                    k++;
                }
                if (k == nums.length) {
                    res = Math.min(res, j - i);

                }
            }
        }
        return res;
    }
}

方法 2:更好的暴力

public class Solution {
    public int findUnsortedSubarray(int[] nums) {
        int l = nums.length, r = 0;
        for (int i = 0; i < nums.length - 1; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[j] < nums[i]) {
                    r = Math.max(r, j);
                    l = Math.min(l, i);
                }
            }
        }
        return r - l < 0 ? 0 : r - l + 1;
    }
}

方法 3:排序

public class Solution {
    public int findUnsortedSubarray(int[] nums) {
        int[] snums = nums.clone();
        Arrays.sort(snums);
        int start = snums.length, end = 0;
        for (int i = 0; i < snums.length; i++) {
            if (snums[i] != nums[i]) {
                start = Math.min(start, i);
                end = Math.max(end, i);
            }
        }
        return (end - start >= 0 ? end - start + 1 : 0);
    }
}

方法 4:使用栈

public class Solution {
    public int findUnsortedSubarray(int[] nums) {
        Stack < Integer > stack = new Stack < Integer > ();
        int l = nums.length, r = 0;
        for (int i = 0; i < nums.length; i++) {
            while (!stack.isEmpty() && nums[stack.peek()] > nums[i])
                l = Math.min(l, stack.pop());
            stack.push(i);
        }
        stack.clear();
        for (int i = nums.length - 1; i >= 0; i--) {
            while (!stack.isEmpty() && nums[stack.peek()] < nums[i])
                r = Math.max(r, stack.pop());
            stack.push(i);
        }
        return r - l > 0 ? r - l + 1 : 0;
    }
}

方法 5:不使用额外空间

public class Solution {
    public int findUnsortedSubarray(int[] nums) {
        int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
        boolean flag = false;
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] < nums[i - 1])
                flag = true;
            if (flag)
                min = Math.min(min, nums[i]);
        }
        flag = false;
        for (int i = nums.length - 2; i >= 0; i--) {
            if (nums[i] > nums[i + 1])
                flag = true;
            if (flag)
                max = Math.max(max, nums[i]);
        }
        int l, r;
        for (l = 0; l < nums.length; l++) {
            if (min < nums[l])
                break;
        }
        for (r = nums.length - 1; r >= 0; r--) {
            if (max > nums[r])
                break;
        }
        return r - l < 0 ? 0 : r - l + 1;
    }
}
最小路径和
class Solution {
    public int minPathSum(int[][] grid) {
        if (grid == null || grid.length == 0 || grid[0].length == 0) {
            return 0;
        }
        int rows = grid.length, columns = grid[0].length;
        int[][] dp = new int[rows][columns];
        dp[0][0] = grid[0][0];
        for (int i = 1; i < rows; i++) {
            dp[i][0] = dp[i - 1][0] + grid[i][0];
        }
        for (int j = 1; j < columns; j++) {
            dp[0][j] = dp[0][j - 1] + grid[0][j];
        }
        for (int i = 1; i < rows; i++) {
            for (int j = 1; j < columns; j++) {
                dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
            }
        }
        return dp[rows - 1][columns - 1];
    }
}
矩阵置零

方法 1:额外存储空间方法

class Solution {
  public void setZeroes(int[][] matrix) {
    int R = matrix.length;
    int C = matrix[0].length;
    Set<Integer> rows = new HashSet<Integer>();
    Set<Integer> cols = new HashSet<Integer>();

    // Essentially, we mark the rows and columns that are to be made zero
    for (int i = 0; i < R; i++) {
      for (int j = 0; j < C; j++) {
        if (matrix[i][j] == 0) {
          rows.add(i);
          cols.add(j);
        }
      }
    }

    // Iterate over the array once again and using the rows and cols sets, update the elements.
    for (int i = 0; i < R; i++) {
      for (int j = 0; j < C; j++) {
        if (rows.contains(i) || cols.contains(j)) {
          matrix[i][j] = 0;
        }
      }
    }
  }
}

方法 2:O(1)空间的暴力

class Solution {
  public void setZeroes(int[][] matrix) {
    int MODIFIED = -1000000;
    int R = matrix.length;
    int C = matrix[0].length;

    for (int r = 0; r < R; r++) {
      for (int c = 0; c < C; c++) {
        if (matrix[r][c] == 0) {
          // We modify the corresponding rows and column elements in place.
          // Note, we only change the non zeroes to MODIFIED
          for (int k = 0; k < C; k++) {
            if (matrix[r][k] != 0) {
              matrix[r][k] = MODIFIED;
            }
          }
          for (int k = 0; k < R; k++) {
            if (matrix[k][c] != 0) {
              matrix[k][c] = MODIFIED;
            }
          }
        }
      }
    }

    for (int r = 0; r < R; r++) {
      for (int c = 0; c < C; c++) {
        // Make a second pass and change all MODIFIED elements to 0 """
        if (matrix[r][c] == MODIFIED) {
          matrix[r][c] = 0;
        }
      }
    }
  }
}
转变数组后最接近目标值的数组和

方法一:枚举 + 二分查找

class Solution {
    public int findBestValue(int[] arr, int target) {
        Arrays.sort(arr);
        int n = arr.length;
        int[] prefix = new int[n + 1];
        for (int i = 1; i <= n; ++i) {
            prefix[i] = prefix[i - 1] + arr[i - 1];
        }
        int r = arr[n - 1];
        int ans = 0, diff = target;
        for (int i = 1; i <= r; ++i) {
            int index = Arrays.binarySearch(arr, i);
            if (index < 0) {
                index = -index - 1;
            }
            int cur = prefix[index] + (n - index) * i;
            if (Math.abs(cur - target) < diff) {
                ans = i;
                diff = Math.abs(cur - target);
            }
        }
        return ans;
    }
}

方法二:双重二分查找

class Solution {
    public int findBestValue(int[] arr, int target) {
        Arrays.sort(arr);
        int n = arr.length;
        int[] prefix = new int[n + 1];
        for (int i = 1; i <= n; ++i) {
            prefix[i] = prefix[i - 1] + arr[i - 1];
        }
        int l = 0, r = arr[n - 1], ans = -1;
        while (l <= r) {
            int mid = (l + r) / 2;
            int index = Arrays.binarySearch(arr, mid);
            if (index < 0) {
                index = -index - 1;
            }
            int cur = prefix[index] + (n - index) * mid;
            if (cur <= target) {
                ans = mid;
                l = mid + 1;
            }
            else {
                r = mid - 1;
            }
        }
        int chooseSmall = check(arr, ans);
        int chooseBig = check(arr, ans + 1);
        return Math.abs(chooseSmall - target) <= Math.abs(chooseBig - target) ? ans : ans + 1;
    }

    public int check(int[] arr, int x) {
        int ret = 0;
        for (int num : arr) {
            ret += Math.min(num, x);
        }
        return ret;
    }
}
两数之和 II - 输入有序数组

方法一:二分查找

class Solution {
    public int[] twoSum(int[] numbers, int target) {
        for (int i = 0; i < numbers.length; ++i) {
            int low = i + 1, high = numbers.length - 1;
            while (low <= high) {
                int mid = (high - low) / 2 + low;
                if (numbers[mid] == target - numbers[i]) {
                    return new int[]{i + 1, mid + 1};
                } else if (numbers[mid] > target - numbers[i]) {
                    high = mid - 1;
                } else {
                    low = mid + 1;
                }
            }
        }
        return new int[]{-1, -1};
    }
}

方法二:双指针

class Solution {
    public int[] twoSum(int[] numbers, int target) {
        int low = 0, high = numbers.length - 1;
        while (low < high) {
            int sum = numbers[low] + numbers[high];
            if (sum == target) {
                return new int[]{low + 1, high + 1};
            } else if (sum < target) {
                ++low;
            } else {
                --high;
            }
        }
        return new int[]{-1, -1};
    }
}
寻找旋转排序数组中的最小值

二分搜索

class Solution {
  public int findMin(int[] nums) {
    // If the list has just one element then return that element.
    if (nums.length == 1) {
      return nums[0];
    }

    // initializing left and right pointers.
    int left = 0, right = nums.length - 1;

    // if the last element is greater than the first element then there is no rotation.
    // e.g. 1 < 2 < 3 < 4 < 5 < 7. Already sorted array.
    // Hence the smallest element is first element. A[0]
    if (nums[right] > nums[0]) {
      return nums[0];
    }
    
    // Binary search way
    while (right >= left) {
      // Find the mid element
      int mid = left + (right - left) / 2;

      // if the mid element is greater than its next element then mid+1 element is the smallest
      // This point would be the point of change. From higher to lower value.
      if (nums[mid] > nums[mid + 1]) {
        return nums[mid + 1];
      }

      // if the mid element is lesser than its previous element then mid element is the smallest
      if (nums[mid - 1] > nums[mid]) {
        return nums[mid];
      }

      // if the mid elements value is greater than the 0th element this means
      // the least value is still somewhere to the right as we are still dealing with elements
      // greater than nums[0]
      if (nums[mid] > nums[0]) {
        left = mid + 1;
      } else {
        // if nums[0] is greater than the mid value then this means the smallest value is somewhere to
        // the left
        right = mid - 1;
      }
    }
    return -1;
  }
}
数组中的 k 个最强值

排序 + 双指针

class Solution {
    public int[] getStrongest(int[] arr, int k) {
        Arrays.sort(arr); // 将数组按数值从小到大排序
        int mid = arr[(arr.length - 1) / 2],index = 0; 
        // mid为数组的中位数,注意题目中定义的中位数与“一般定义”不同
        int[] ans = new int[k];
        int left = 0,right = arr.length - 1;
        while(index < k) { // 直到获取k个数为止
            int a = Math.abs(arr[left] - mid),b = Math.abs(arr[right] - mid);
            /* 按规则获取数字 */
            if(a > b) {
                ans[index] = arr[left];left++;index++;
            }
            else { // 由于数组中的数字按升序排序,因此右边的数总是大于左边的
                ans[index] = arr[right];right--;index++;
            } 
        }
        return ans;
    }
}
寻找重复数

方法一:二分查找

class Solution {
    public int findDuplicate(int[] nums) {
        int n = nums.length;
        int l = 1, r = n - 1, ans = -1;
        while (l <= r) {
            int mid = (l + r) >> 1;
            int cnt = 0;
            for (int i = 0; i < n; ++i) {
                if (nums[i] <= mid) {
                    cnt++;
                }
            }
            if (cnt <= mid) {
                l = mid + 1;
            } else {
                r = mid - 1;
                ans = mid;
            }
        }
        return ans;
    }
}

方法二:快慢指针

class Solution {
    public int findDuplicate(int[] nums) {
        int slow = 0, fast = 0;
        do {
            slow = nums[slow];
            fast = nums[nums[fast]];
        } while (slow != fast);
        slow = 0;
        while (slow != fast) {
            slow = nums[slow];
            fast = nums[fast];
        }
        return slow;
    }
}
乘积最大子数组

动态规划

//动态方程
class Solution {
    public int maxProduct(int[] nums) {
        int length = nums.length;
        int[] maxF = new int[length];
        int[] minF = new int[length];
        System.arraycopy(nums, 0, maxF, 0, length);
        System.arraycopy(nums, 0, minF, 0, length);
        for (int i = 1; i < length; ++i) {
            maxF[i] = Math.max(maxF[i - 1] * nums[i], Math.max(nums[i], minF[i - 1] * nums[i]));
            minF[i] = Math.min(minF[i - 1] * nums[i], Math.min(nums[i], maxF[i - 1] * nums[i]));
        }
        int ans = maxF[0];
        for (int i = 1; i < length; ++i) {
            ans = Math.max(ans, maxF[i]);
        }
        return ans;
    }
}

//空间优化
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;
    }
}
搜索插入位置
class Solution {
    public int searchInsert(int[] nums, int target) {
        int n = nums.length;
        int left = 0, right = n - 1, ans = n;
        while (left <= right) {
            int mid = ((right - left) >> 1) + left;
            if (target <= nums[mid]) {
                ans = mid;
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return ans;
    }
}
删除排序数组中的重复项
public int removeDuplicates(int[] nums) {
    if (nums.length == 0) return 0;
    int i = 0;
    for (int j = 1; j < nums.length; j++) {
        if (nums[j] != nums[i]) {
            i++;
            nums[i] = nums[j];
        }
    }
    return i + 1;
}
最长连续序列
class Solution {
    public int longestConsecutive(int[] nums) {
        Set<Integer> num_set = new HashSet<Integer>();
        for (int num : nums) {
            num_set.add(num);
        }
        int longestStreak = 0;
        for (int num : num_set) {
            if (!num_set.contains(num - 1)) {
                int currentNum = num;
                int currentStreak = 1;
                while (num_set.contains(currentNum + 1)) {
                    currentNum += 1;
                    currentStreak += 1;
                }
                longestStreak = Math.max(longestStreak, currentStreak);
            }
        }
        return longestStreak;
    }
}
最长的斐波那契子序列的长度

方法二:动态规划

class Solution {
    public int lenLongestFibSubseq(int[] A) {
        int N = A.length;
        Map<Integer, Integer> index = new HashMap();
        for (int i = 0; i < N; ++i)
            index.put(A[i], i);

        Map<Integer, Integer> longest = new HashMap();
        int ans = 0;

        for (int k = 0; k < N; ++k)
            for (int j = 0; j < k; ++j) {
                int i = index.getOrDefault(A[k] - A[j], -1);
                if (i >= 0 && i < j) {
                    // Encoding tuple (i, j) as integer (i * N + j)
                    int cand = longest.getOrDefault(i * N + j, 2) + 1;
                    longest.put(j * N + k, cand);
                    ans = Math.max(ans, cand);
                }
            }

        return ans >= 3 ? ans : 0;
    }
}
盛最多水的容器
public class Solution {
    public int maxArea(int[] height) {
        int l = 0, r = height.length - 1;
        int ans = 0;
        while (l < r) {
            int area = Math.min(height[l], height[r]) * (r - l);
            ans = Math.max(ans, area);
            if (height[l] <= height[r]) {
                ++l;
            }
            else {
                --r;
            }
        }
        return ans;
    }
}
使用最小花费爬楼梯
class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int f1 = 0, f2 = 0;
        for (int i = cost.length - 1; i >= 0; --i) {
            int f0 = cost[i] + Math.min(f1, f2);
            f2 = f1;
            f1 = f0;
        }
        return Math.min(f1, f2);
    }
}
最长湍流子数组
class Solution {
    public int maxTurbulenceSize(int[] A) {
        int N = A.length;
        int ans = 1;
        int anchor = 0;

        for (int i = 1; i < N; ++i) {
            int c = Integer.compare(A[i-1], A[i]);
            if (i == N-1 || c * Integer.compare(A[i], A[i+1]) != -1) {
                if (c != 0) ans = Math.max(ans, i - anchor + 1);
                anchor = i;
            }
        }

        return ans;
    }
}
最大子序和

方法一:动态规划

class Solution {
    public int maxSubArray(int[] nums) {
        int pre = 0, maxAns = nums[0];
        for (int x : nums) {
            pre = Math.max(pre + x, x);
            maxAns = Math.max(maxAns, pre);
        }
        return maxAns;
    }
}

方法二:分治

class Solution {
    public class Status {
        public int lSum, rSum, mSum, iSum;

        public Status(int lSum, int rSum, int mSum, int iSum) {
            this.lSum = lSum;
            this.rSum = rSum;
            this.mSum = mSum;
            this.iSum = iSum;
        }
    }

    public int maxSubArray(int[] nums) {
        return getInfo(nums, 0, nums.length - 1).mSum;
    }

    public Status getInfo(int[] a, int l, int r) {
        if (l == r) {
            return new Status(a[l], a[l], a[l], a[l]);
        }
        int m = (l + r) >> 1;
        Status lSub = getInfo(a, l, m);
        Status rSub = getInfo(a, m + 1, r);
        return pushUp(lSub, rSub);
    }

    public Status pushUp(Status l, Status r) {
        int iSum = l.iSum + r.iSum;
        int lSum = Math.max(l.lSum, l.iSum + r.lSum);
        int rSum = Math.max(r.rSum, r.iSum + l.rSum);
        int mSum = Math.max(Math.max(l.mSum, r.mSum), l.rSum + r.lSum);
        return new Status(lSum, rSum, mSum, iSum);
    }
}
最长重复子数组

方法一:动态规划

class Solution {
    public int findLength(int[] A, int[] B) {
        int n = A.length, m = B.length;
        int[][] dp = new int[n + 1][m + 1];
        int ans = 0;
        for (int i = n - 1; i >= 0; i--) {
            for (int j = m - 1; j >= 0; j--) {
                dp[i][j] = A[i] == B[j] ? dp[i + 1][j + 1] + 1 : 0;
                ans = Math.max(ans, dp[i][j]);
            }
        }
        return ans;
    }
}

方法二:滑动窗口

class Solution {
    public int findLength(int[] A, int[] B) {
        int n = A.length, m = B.length;
        int ret = 0;
        for (int i = 0; i < n; i++) {
            int len = Math.min(m, n - i);
            int maxlen = maxLength(A, B, i, 0, len);
            ret = Math.max(ret, maxlen);
        }
        for (int i = 0; i < m; i++) {
            int len = Math.min(n, m - i);
            int maxlen = maxLength(A, B, 0, i, len);
            ret = Math.max(ret, maxlen);
        }
        return ret;
    }

    public int maxLength(int[] A, int[] B, int addA, int addB, int len) {
        int ret = 0, k = 0;
        for (int i = 0; i < len; i++) {
            if (A[addA + i] == B[addB + i]) {
                k++;
            } else {
                k = 0;
            }
            ret = Math.max(ret, k);
        }
        return ret;
    }
}

方法三:二分查找 + 哈希

class Solution {
    int mod = 1000000009;
    int base = 113;

    public int findLength(int[] A, int[] B) {
        int left = 1, right = Math.min(A.length, B.length) + 1;
        while (left < right) {
            int mid = (left + right) >> 1;
            if (check(A, B, mid)) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return left - 1;
    }

    public boolean check(int[] A, int[] B, int len) {
        long hashA = 0;
        for (int i = 0; i < len; i++) {
            hashA = (hashA * base + A[i]) % mod;
        }
        Set<Long> bucketA = new HashSet<Long>();
        bucketA.add(hashA);
        long mult = qPow(base, len - 1);
        for (int i = len; i < A.length; i++) {
            hashA = ((hashA - A[i - len] * mult % mod + mod) % mod * base + A[i]) % mod;
            bucketA.add(hashA);
        }
        long hashB = 0;
        for (int i = 0; i < len; i++) {
            hashB = (hashB * base + B[i]) % mod;
        }
        if (bucketA.contains(hashB)) {
            return true;
        }
        for (int i = len; i < B.length; i++) {
            hashB = ((hashB - B[i - len] * mult % mod + mod) % mod * base + B[i]) % mod;
            if (bucketA.contains(hashB)) {
                return true;
            }
        }
        return false;
    }
    
    // 使用快速幂计算 x^n % mod 的值
    public long qPow(long x, long n) {
        long ret = 1;
        while (n != 0) {
            if ((n & 1) != 0) {
                ret = ret * x % mod;
            }
            x = x * x % mod;
            n >>= 1;
        }
        return ret;
    }
}
岛屿的最大面积

方法一:深度优先搜索

class Solution {
    public int maxAreaOfIsland(int[][] grid) {
        int ans = 0;
        for (int i = 0; i != grid.length; ++i) {
            for (int j = 0; j != grid[0].length; ++j) {
                ans = Math.max(ans, dfs(grid, i, j));
            }
        }
        return ans;
    }

    public int dfs(int[][] grid, int cur_i, int cur_j) {
        if (cur_i < 0 || cur_j < 0 || cur_i == grid.length || cur_j == grid[0].length || grid[cur_i][cur_j] != 1) {
            return 0;
        }
        grid[cur_i][cur_j] = 0;
        int[] di = {0, 0, 1, -1};
        int[] dj = {1, -1, 0, 0};
        int ans = 1;
        for (int index = 0; index != 4; ++index) {
            int next_i = cur_i + di[index], next_j = cur_j + dj[index];
            ans += dfs(grid, next_i, next_j);
        }
        return ans;
    }
}

方法二:深度优先搜索 + 栈

class Solution {
    public int maxAreaOfIsland(int[][] grid) {
        int ans = 0;
        for (int i = 0; i != grid.length; ++i) {
            for (int j = 0; j != grid[0].length; ++j) {
                int cur = 0;
                Deque<Integer> stacki = new LinkedList<Integer>();
                Deque<Integer> stackj = new LinkedList<Integer>();
                stacki.push(i);
                stackj.push(j);
                while (!stacki.isEmpty()) {
                    int cur_i = stacki.pop(), cur_j = stackj.pop();
                    if (cur_i < 0 || cur_j < 0 || cur_i == grid.length || cur_j == grid[0].length || grid[cur_i][cur_j] != 1) {
                        continue;
                    }
                    ++cur;
                    grid[cur_i][cur_j] = 0;
                    int[] di = {0, 0, 1, -1};
                    int[] dj = {1, -1, 0, 0};
                    for (int index = 0; index != 4; ++index) {
                        int next_i = cur_i + di[index], next_j = cur_j + dj[index];
                        stacki.push(next_i);
                        stackj.push(next_j);
                    }
                }
                ans = Math.max(ans, cur);
            }
        }
        return ans;
    }
}

方法三:广度优先搜索

class Solution {
    public int maxAreaOfIsland(int[][] grid) {
        int ans = 0;
        for (int i = 0; i != grid.length; ++i) {
            for (int j = 0; j != grid[0].length; ++j) {
                int cur = 0;
                Queue<Integer> queuei = new LinkedList<Integer>();
                Queue<Integer> queuej = new LinkedList<Integer>();
                queuei.offer(i);
                queuej.offer(j);
                while (!queuei.isEmpty()) {
                    int cur_i = queuei.poll(), cur_j = queuej.poll();
                    if (cur_i < 0 || cur_j < 0 || cur_i == grid.length || cur_j == grid[0].length || grid[cur_i][cur_j] != 1) {
                        continue;
                    }
                    ++cur;
                    grid[cur_i][cur_j] = 0;
                    int[] di = {0, 0, 1, -1};
                    int[] dj = {1, -1, 0, 0};
                    for (int index = 0; index != 4; ++index) {
                        int next_i = cur_i + di[index], next_j = cur_j + dj[index];
                        queuei.offer(next_i);
                        queuej.offer(next_j);
                    }
                }
                ans = Math.max(ans, cur);
            }
        }
        return ans;
    }
}
组合总和

img

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        List<Integer> combine = new ArrayList<Integer>();
        dfs(candidates, target, ans, combine, 0);
        return ans;
    }
    public void dfs(int[] candidates, int target, List<List<Integer>> ans, List<Integer> combine, int idx) {
        if (idx == candidates.length) {
            return;
        }
        if (target == 0) {
            ans.add(new ArrayList<Integer>(combine));
            return;
        }
        // 直接跳过
        dfs(candidates, target, ans, combine, idx + 1);
        // 选择当前数
        if (target - candidates[idx] >= 0) {
            combine.add(candidates[idx]);
            dfs(candidates, target - candidates[idx], ans, combine, idx);
            combine.remove(combine.size() - 1);
        }
    }
}
颜色分类

方法一:单指针

class Solution {
    public void sortColors(int[] nums) {
        int n = nums.length;
        int ptr = 0;
        for (int i = 0; i < n; ++i) {
            if (nums[i] == 0) {
                int temp = nums[i];
                nums[i] = nums[ptr];
                nums[ptr] = temp;
                ++ptr;
            }
        }
        for (int i = ptr; i < n; ++i) {
            if (nums[i] == 1) {
                int temp = nums[i];
                nums[i] = nums[ptr];
                nums[ptr] = temp;
                ++ptr;
            }
        }
    }
}

方法二:双指针

class Solution {
    public void sortColors(int[] nums) {
        int n = nums.length;
        int p0 = 0, p1 = 0;
        for (int i = 0; i < n; ++i) {
            if (nums[i] == 1) {
                int temp = nums[i];
                nums[i] = nums[p1];
                nums[p1] = temp;
                ++p1;
            } else if (nums[i] == 0) {
                int temp = nums[i];
                nums[i] = nums[p0];
                nums[p0] = temp;
                if (p0 < p1) {
                    temp = nums[i];
                    nums[i] = nums[p1];
                    nums[p1] = temp;
                }
                ++p0;
                ++p1;
            }
        }
    }
}

方法三:双指针

class Solution {
    public void sortColors(int[] nums) {
        int n = nums.length;
        int p0 = 0, p2 = n - 1;
        for (int i = 0; i <= p2; ++i) {
            while (i <= p2 && nums[i] == 2) {
                int temp = nums[i];
                nums[i] = nums[p2];
                nums[p2] = temp;
                --p2;
            }
            if (nums[i] == 0) {
                int temp = nums[i];
                nums[i] = nums[p0];
                nums[p0] = temp;
                ++p0;
            }
        }
    }
}
接雨水

方法 1:暴力

public int trap(int[] height) {
    int ans = 0;
    int size = height.length;
    for (int i = 1; i < size - 1; i++) {
        int max_left = 0, max_right = 0;
        for (int j = i; j >= 0; j--) { //Search the left part for max bar size
            max_left = Math.max(max_left, height[j]);
        }
        for (int j = i; j < size; j++) { //Search the right part for max bar size
            max_right = Math.max(max_right, height[j]);
        }
        ans += Math.min(max_left, max_right) - height[i];
    }
    return ans;
}

方法 2:动态编程

public int trap(int[] height) {
    if (height == null || height.length == 0)
        return 0;
    int ans = 0;
    int size = height.length;
    int[] left_max = new int[size];
    int[] right_max = new int[size];
    left_max[0] = height[0];
    for (int i = 1; i < size; i++) {
        left_max[i] = Math.max(height[i], left_max[i - 1]);
    }
    right_max[size - 1] = height[size - 1];
    for (int i = size - 2; i >= 0; i--) {
        right_max[i] = Math.max(height[i], right_max[i + 1]);
    }
    for (int i = 1; i < size - 1; i++) {
        ans += Math.min(left_max[i], right_max[i]) - height[i];
    }
    return ans;
}

方法 3:栈的应用

public int trap(int[] height) {
    int ans = 0, current = 0;
    Deque<Integer> stack = new LinkedList<Integer>();
    while (current < height.length) {
        while (!stack.isEmpty() && height[current] > height[stack.peek()]) {
            int top = stack.pop();
            if (stack.isEmpty())
                break;
            int distance = current - stack.peek() - 1;
            int bounded_height = Math.min(height[current], height[stack.peek()]) - height[top];
            ans += distance * bounded_height;
        }
        stack.push(current++);
    }
    return ans;
}

方法 4:使用双指针

public int trap(int[] height) {
    int left = 0, right = height.length - 1;
    int ans = 0;
    int left_max = 0, right_max = 0;
    while (left < right) {
        if (height[left] < height[right]) {
            if (height[left] >= left_max) {
                left_max = height[left];
            } else {
                ans += (left_max - height[left]);
            }
            ++left;
        } else {
            if (height[right] >= right_max) {
                right_max = height[right];
            } else {
                ans += (right_max - height[right]);
            }
            --right;
        }
    }
    return ans;
}
在使用Python来安装geopandas包时,由于geopandas依赖于几个其他的Python库(如GDAL, Fiona, Pyproj, Shapely等),因此安装过程可能需要一些额外的步骤。以下是一个基本的安装指南,适用于大多数用户: 使用pip安装 确保Python和pip已安装: 首先,确保你的计算机上已安装了Python和pip。pip是Python的包管理工具,用于安装和管理Python包。 安装依赖库: 由于geopandas依赖于GDAL, Fiona, Pyproj, Shapely等库,你可能需要先安装这些库。通常,你可以通过pip直接安装这些库,但有时候可能需要从其他源下载预编译的二进制包(wheel文件),特别是GDAL和Fiona,因为它们可能包含一些系统级的依赖。 bash pip install GDAL Fiona Pyproj Shapely 注意:在某些系统上,直接使用pip安装GDAL和Fiona可能会遇到问题,因为它们需要编译一些C/C++代码。如果遇到问题,你可以考虑使用conda(一个Python包、依赖和环境管理器)来安装这些库,或者从Unofficial Windows Binaries for Python Extension Packages这样的网站下载预编译的wheel文件。 安装geopandas: 在安装了所有依赖库之后,你可以使用pip来安装geopandas。 bash pip install geopandas 使用conda安装 如果你正在使用conda作为你的Python包管理器,那么安装geopandas和它的依赖可能会更简单一些。 创建一个新的conda环境(可选,但推荐): bash conda create -n geoenv python=3.x anaconda conda activate geoenv 其中3.x是你希望使用的Python版本。 安装geopandas: 使用conda-forge频道来安装geopandas,因为它提供了许多地理空间相关的包。 bash conda install -c conda-forge geopandas 这条命令会自动安装geopandas及其所有依赖。 注意事项 如果你在安装过程中遇到任何问题,比如编译错误或依赖问题,请检查你的Python版本和pip/conda的版本是否是最新的,或者尝试在不同的环境中安装。 某些库(如GDAL)可能需要额外的系统级依赖,如地理空间库(如PROJ和GEOS)。这些依赖可能需要单独安装,具体取决于你的操作系统。 如果你在Windows上遇到问题,并且pip安装失败,尝试从Unofficial Windows Binaries for Python Extension Packages网站下载相应的wheel文件,并使用pip进行安装。 脚本示例 虽然你的问题主要是关于如何安装geopandas,但如果你想要一个Python脚本来重命名文件夹下的文件,在原始名字前面加上字符串"geopandas",以下是一个简单的示例: python import os # 指定文件夹路径 folder_path = 'path/to/your/folder' # 遍历文件夹中的文件 for filename in os.listdir(folder_path): # 构造原始文件路径 old_file_path = os.path.join(folder_path, filename) # 构造新文件名 new_filename = 'geopandas_' + filename # 构造新文件路径 new_file_path = os.path.join(folder_path, new_filename) # 重命名文件 os.rename(old_file_path, new_file_path) print(f'Renamed "{filename}" to "{new_filename}"') 请确保将'path/to/your/folder'替换为你想要重命名文件的实际文件夹路径。
在使用Python来安装geopandas包时,由于geopandas依赖于几个其他的Python库(如GDAL, Fiona, Pyproj, Shapely等),因此安装过程可能需要一些额外的步骤。以下是一个基本的安装指南,适用于大多数用户: 使用pip安装 确保Python和pip已安装: 首先,确保你的计算机上已安装了Python和pip。pip是Python的包管理工具,用于安装和管理Python包。 安装依赖库: 由于geopandas依赖于GDAL, Fiona, Pyproj, Shapely等库,你可能需要先安装这些库。通常,你可以通过pip直接安装这些库,但有时候可能需要从其他源下载预编译的二进制包(wheel文件),特别是GDAL和Fiona,因为它们可能包含一些系统级的依赖。 bash pip install GDAL Fiona Pyproj Shapely 注意:在某些系统上,直接使用pip安装GDAL和Fiona可能会遇到问题,因为它们需要编译一些C/C++代码。如果遇到问题,你可以考虑使用conda(一个Python包、依赖和环境管理器)来安装这些库,或者从Unofficial Windows Binaries for Python Extension Packages这样的网站下载预编译的wheel文件。 安装geopandas: 在安装了所有依赖库之后,你可以使用pip来安装geopandas。 bash pip install geopandas 使用conda安装 如果你正在使用conda作为你的Python包管理器,那么安装geopandas和它的依赖可能会更简单一些。 创建一个新的conda环境(可选,但推荐): bash conda create -n geoenv python=3.x anaconda conda activate geoenv 其中3.x是你希望使用的Python版本。 安装geopandas: 使用conda-forge频道来安装geopandas,因为它提供了许多地理空间相关的包。 bash conda install -c conda-forge geopandas 这条命令会自动安装geopandas及其所有依赖。 注意事项 如果你在安装过程中遇到任何问题,比如编译错误或依赖问题,请检查你的Python版本和pip/conda的版本是否是最新的,或者尝试在不同的环境中安装。 某些库(如GDAL)可能需要额外的系统级依赖,如地理空间库(如PROJ和GEOS)。这些依赖可能需要单独安装,具体取决于你的操作系统。 如果你在Windows上遇到问题,并且pip安装失败,尝试从Unofficial Windows Binaries for Python Extension Packages网站下载相应的wheel文件,并使用pip进行安装。 脚本示例 虽然你的问题主要是关于如何安装geopandas,但如果你想要一个Python脚本来重命名文件夹下的文件,在原始名字前面加上字符串"geopandas",以下是一个简单的示例: python import os # 指定文件夹路径 folder_path = 'path/to/your/folder' # 遍历文件夹中的文件 for filename in os.listdir(folder_path): # 构造原始文件路径 old_file_path = os.path.join(folder_path, filename) # 构造新文件名 new_filename = 'geopandas_' + filename # 构造新文件路径 new_file_path = os.path.join(folder_path, new_filename) # 重命名文件 os.rename(old_file_path, new_file_path) print(f'Renamed "{filename}" to "{new_filename}"') 请确保将'path/to/your/folder'替换为你想要重命名文件的实际文件夹路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值