跳至主要內容

数据结构与算法

程序员李某某大约 4 分钟

数据结构与算法

算法

质数

枚举

o(nolan)

	//判断某数是否为质数
	public boolean IsPrime(int n) {
		for (int i = 2; i <= Math.sqrt(n); i++) {
		    if (n % i == 0) {
				return false;
			}
		}
		return true;
	}

	//计数
	public int testIsPrime(int n){
		int count = 0;
		if (n==2){
			return count=1;
		}
		for (int i = 2; i < n; i++) {
		  count +=  IsPrime(i)? 1:0;
		}
		return count;
	}

埃式筛

标记质数的倍数,存在重复标记,o(nloglogn)

public int testPrimeNumber(int n) {
		boolean[] isPrime = new boolean[n+1];
		Arrays.fill(isPrime, true);
		int count = 0;

		for (int i = 2; i < isPrime.length; i++) {
			//计数,并把质数的倍数标记为false
			if (isPrime[i]) {
				count++;
				//从 (i * i) 开始,[i * (i-1)]已经被上一轮i标记过,
				//如i=2时标记4,6,,10...,	i=3时应标记6,9,12...,但6已经标记过了无须再标记
				for (int j = i * i; j < isPrime.length; j += i) {
					isPrime[j] = false;
				}
			}
		}
		return count;
	}

线性筛

解决重复标记,o(n)

	private int testIsPrime3(int n) {
		boolean[] isPrime = new boolean[n + 1];
		Arrays.fill(isPrime, true);
		ArrayList<Integer> primes = new ArrayList<>();

		for (int i = 2; i < n + 1; i++) {
			//计数,并把质数的倍数标记为false
			if (isPrime[i]) {
				primes.add(i);
			}
			//i=2,标记4
			//i=3,标记6,9
			//i=4,标记8
			//i=5,标记10,15,25
			//标记:所有整数 与 当前质数集合的每个质数 的乘积
			for (int j = 0; j < primes.size() && i * primes.get(j) < n + 1; j++) {
				isPrime[i * primes.get(j)] = false;
				//避免重复标记
				//合数 = 若干质数的乘积
				//6被2整除,6定是合数,2是最小的质数,6*3=2*3*3=2*(3*3)=9*2,...
				//9被3整除,9定是合数,3是最小的质数,9*5=3*3*5=3*(3*5)=15*3,...
				//35被5整除,35定是合数,5是最小的质数,35*7=5*7*7=5*(7*7)=49*5,...
				if (i % primes.get(j) == 0) {
					break;
				}
			}
		}
		return primes.size();
	}

高效计算2*8

2 << 3 
// 8 << 1

杨辉三角

public void testYangHui() {
	int[][] array= new int[10][];
	for (int i = 0; i < array.length; i++) {
		array[i] = new int[i+1];
		for (int j = 0; j <= i; j++) {
			array[i][0] = array[i][i] = 1;
			if (i > 0 && j > 0 && j < i){
				array[i][j] = array[i-1][j-1] + array[i-1][j];
			}
			System.out.print(array[i][j] + "t");
		}
		System.out.println();
	}
}

回形数

	public static void testHuiXingShu() {
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入边长: ");
		int n = scanner.nextInt();
		int[][] ints = new int[n][n];

		int count = 1;
		for (int i = 0; i < n / 2 + 1; i++) {  				//圈数
			for (int j = i; j < n - i - 1; j++) {				
				ints[i][j] = count++;											//上
			}
			for (int j = i; j < n - i - 1; j++) {
				ints[j][n - i - 1] = count++;							//右
			}
			for (int j = i; j < n - i - 1; j++) {
				ints[n - i - 1][n - j - 1] = count++;			//下
			}
			for (int j = i; j < n - i - 1; j++) {
				ints[n - j - 1][i] = count++;							//左
			}
		}

    //奇数时,最后一次循环的内循环进不去
		if (n % 2 != 0) {
			ints[n / 2][n / 2] = n * n;
		}

		//遍历
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				System.out.print(ints[i][j] + "t");
			}
			System.out.println();
		}
	}
public class Main {
 
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入一个数字");
        int num = scanner.nextInt();
        int[][] huiXingShu = new int[num][num];
 
        int count = 0; // 要显示的数据
        int maxX = num - 1; // x横轴的最大下标
        int maxY = num - 1; // Y纵轴的最大下标
        int minX = 0; // x横轴的最小下标
        int minY = 0; // Y纵轴的最小下标
        while (minX <= maxX) {  //直到X横轴线最小下标比最大下标还大时就退出循环 说明已经把值赋到最后一个了
            for (int x = minX; x <= maxX; x++) {    //向右 从最小到最大下标递增
                huiXingShu[minY][x] = ++count;  //必须++count 不然count++第一次会赋值为0
            }
            minY++;     //说明Y纵轴的最小下标+1 向右已经赋值完一行了
            for (int y = minY; y <= maxY; y++) {    //向下 从最小到最大下标递增
                huiXingShu[y][maxX] = ++count;
            }
            maxX--;     //以上同理不再赘述
            for (int x = maxX; x >= minX; x--) {    //向左 从最小到最大下标递减
                huiXingShu[maxY][x] = ++count;
            }
            maxY--;
            for (int y = maxY; y >= minY; y--) {    //向上 从最小到最大下标递减
                huiXingShu[y][minX] = ++count;
            }
            minX++;
        }
 
        // 遍历
        for (int[] anhuiXingShu : huiXingShu) {
            for (int anAnhuiXingShu : anhuiXingShu) {
                System.out.print(anAnhuiXingShu + "t");
            }
            System.out.println();
        }
    }
}

查找

线性查找

public void testLinearSearch(){
	int[] ints = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
	int a = 13;
	boolean isFlag = true;
	for (int i = 0; i < ints.length; i++) {
		if (ints[i] == a) {
			System.out.println(a + "的索引为" + i);
			isFlag = false;
			break;
		}
	}
	if (isFlag) {
		System.out.println(a + "未找到");
	}
}

二分法查找

public void testDichotomySearch(){
	int[] ints = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
	int a = 23;
	int head = 0; //头指针
	int end = ints.length - 1; //尾指针
	boolean isFlag = true;
	while (head <= end) {
		int middle = (head + end)/2;
		
		if (ints[middle] == a) {
			System.out.println(a + "的索引为" + (middle));
			isFlag = false;
			break;
		}else if (a > ints[middle]){
			head = middle + 1;
		}else {
			end = middle - 1;
		}
	}
  
	if (isFlag) {
		System.out.println("未找到");
	}
}

排序

冒泡排序

public  void testBubbleSort(){
	int[] ints = new int[]{-10,14,4,24,-9,-1,15,19,4};
	System.out.println("开始排序");
	int temp = ints[0];
	for (int i = 0; i < ints.length - 1; i++){  //轮数
		boolean isFlag = true;  //isFlag为true,即未交换过,就不在进行大轮循环
		for (int j = 0; j < ints.length - i - 1; j++) {  //交换次数
			if (ints[j] > ints[j + 1]) {
				temp = ints[j];
				ints[j] = ints[j + 1];
				ints[j + 1] = temp;
				isFlag = false;
			}
		}
		if (isFlag) break;
	}
	System.out.println(Arrays.toString(ints));
}

String

trim()

部分反转

出现次数

最大相同子串

自然顺序排序

上次编辑于:
贡献者: ext.liyuanhao3