java编程参考笔记

一、算法

1.1 字符串操作相关

1 字符串只包括数字和*,重排使所有的*在左,数字在右并保持顺序不变.

public class Demo {
    
    public static void main(String[] args) {
        String str = "123";
        try {
            String res = dealStr2(str);
            System.out.println(res);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    /**
     * 方式一:  字符串转char数组, 数字元素后移, 前面填充*
     */
    public static String dealStr(String str) throws Exception {
        // 以下情况(str是:null,纯数字,纯*号), 则直接返回原字符串
        if (null == str || str.matches("\\d+") || str.matches("\\*+")) {
            return str;
        }
        // 如果非数字与*组合, 直接抛出异常
        if (!str.matches("[\\d\\*]+")) {
            throw new Exception("输入了非法的字符串!");
        }

        // 字符串转字符数组, 数字元素向后移动
        char[] chars = str.toCharArray();
        int index = str.length() - 1;
        for (int i = str.length() - 1; i >= 0; i--) {
            if (chars[i] != '*') {
                chars[index--] = chars[i];
            }
        }
        // 填补前面的*号
        for (; index >= 0; index--) {
            chars[index] = '*';
        }

        // 字符数组转string后返回
        return new String(chars);
    }


    /**
     * 方式二: 正则移除字符串中的数字 + 正则移除字符串中的*号
     */
    public static String dealStr2(String str) throws Exception {
        // 以下情况(str是:null,纯数字,纯*号), 则直接返回原字符串
        if (null == str || str.matches("\\d+") || str.matches("\\*+")) {
            return str;
        }
        // 如果非数字与*组合, 直接抛出异常
        if (!str.matches("[\\d\\*]+")) {
            throw new Exception("输入了非法的字符串!");
        }

        // 返回结果
        return str.replaceAll("\\d", "") + str.replaceAll("\\*", "");
    }

}

1.2 int数组操作

1 一个int数组,使其奇数在左,偶数在右.

1 思路
1)左指针从数组的左侧起找偶数,找到就停止; 
2)右指针从数组的右侧起找奇数,找到就停止;
3)交换两个指针上的元素;
4)重复上面的步骤,两个指针碰到一起就结束;


2 代码demo
private static void sort(int[] array) {
    // 1 特殊情况的预处理
    if (null == array || array.length == 1) {
        return;
    }

    // 定义变量
    int left = 0;
    int right = array.length - 1;
    int temp;
    while (left < right) {
        // 1 从左边开始查找偶数
        while (left < right && array[left] % 2 == 1) {
            left++;
        }

        // 2 从右边开始查找奇数
        while (right > left && array[right] % 2 == 0) {
            right--;
        }

        // 3 交换两个指针上的异类元素
        if (left < right) {
            temp = array[left];
            array[left] = array[right];
            array[right] = temp;
        }
    }
}

 

2 两个很大的整数相加

1 思想: 模拟加法运算
1)以字符串的形式传入两个整数
2)字符串的元素存入两个int数组
3)数组中对应的元素相加(分割的思想)

2 代码demo
private static String add(String s1, String s2) {
    // 1 统一化,s1存较大的是,s2存较小的数
    if (s1.length() < s2.length()) {
        String temp;
        temp = s1;
        s1 = s2;
        s2 = temp;
    }

    // 2 构造3个int[]容器
    int len = s1.length();
    int[] x1 = new int[len]; //存放参数1
    int[] x2 = new int[len]; //存放参数2
    int[] sum = new int[len + 1]; //存放两个参数的和以及进位

    // 3 参数1的各位数字存入容器
    for (int i = 0; i < len; i++) {
        x1[i] = s1.charAt(i) - '0';
    }

    // 4 参数2的各位数字存入容器
    int t = len - s2.length();
    for (int i = t; i < len; i++) {
        x2[i] = s2.charAt(i - t) - '0';
    }

    // 5 逐位求两个参数的和,并存入和容器中
    for (int i = len - 1; i >= 0; i--) {
        sum[i + 1] += x1[i] + x2[i]; //求本位上的总和
        sum[i] = sum[i + 1] / 10; //向高位的进位
        sum[i + 1] %= 10; // 本位的剩余
    }

    // 6 转结果
    StringBuilder result = new StringBuilder();
    for (int aSum : sum) {
        result.append(aSum);
    }

    // 7 去前面0的操作
    String result2 = result.toString();
    int count = 0;
    int len2 = result2.length();
    while (count < len2 && result.charAt(count) == '0') {
        count++;
    }

    return result2.substring(count);
}

3 判断两个int数组是否有相同的元素.

1 思路
1)两个数组中的元素放入分别(除去自身数组中有相同元素的影响)放入Set集合中,求出这两个set集合的元素个数之和size1;
2)把一个set中的所有元素放入另一个set中,求出此集合的元素个数size2;
3)如果size2<size1,则说明两个数组中有相同的元素,否则两个数组中没有相同的元素.


2 代码demo
private static boolean isSame(int[] array, int[] array2) {

    // 1 定义两个去重的容器
    Set<Integer> set = new HashSet<Integer>();
    Set<Integer> set2 = new HashSet<Integer>();
    
    // 2 两个数组的元素分别放入两个Set集合(去除自己中的重复元素)
    for (int i : array) {
        set.add(i);
    }
    for (int i : array2) {
        set2.add(i);
    }

    // 3 长度比较法
    int len = set.size() + set2.size();
    set.addAll(set2);

    return len > set.size();
}

 4 求一个int数组的子数组元素之和的最大值.

1 思路
定住左边界之后, 依次移动右边界,依次遍历所有子数组的和值, 从而找出最大值.

2 代码demo
private static int getSum(int[] array) {
    int max = array[0];
    int sum;
    for (int i = 0; i < array.length; i++) {
        sum = 0;
        for (int j = i; j < array.length; j++) {
            sum += array[j];
            if (max < sum) {
                max = sum;
            }
        }
    }
    return max;
}

1.3 二分查找

1 数组必须是升序排列的

2 代码demo
/**
* 找到返回对应位置的索引, 其他情况返回-1
*/
private static int binarySort(int[] array, int value) {
    // 1 特殊情况处理
    if (null == array) {
        return -1;
    }

    // 定义变量,进行二分查找
    int left = 0;
    int right = array.length - 1;
    int middle;
    while (left <= right) {
        // 中间位置的索引
        middle = (left + right) / 2;

        // 找到处理
        if (value == array[middle]) {
            return middle;
        }

        // value值小时, 修改右指针
        if (value < array[middle]) {
            right = middle - 1;
        }

        // value值大时, 修改左指针
        if (value > array[middle]) {
            left = middle + 1;
        }
    }
    
    // 找不到时返回-1
    return -1;
}

1.4 排序

1 插入排序

1 思想:从第二个元素起,依次插入到前面已经排好序的数组中(挖坑填坑法). 

2 代码demo
private static void insertSort(int[] array) {
    // 1 特殊情况处理
    if (null == array || array.length == 1) {
        return;
    }

    // 2 逐位放到正确的位置上
    int tmp;
    int j;
    for (int i = 1; i < array.length; i++) {
        tmp = array[i];
        for (j = i - 1; j >= 0; j--) {
            if (array[j] <= tmp) {
                break;
            }
            array[j + 1] = array[j];
        }
       
        array[j + 1] = tmp; // 把你存放到正确位置
    }
}

 

2 希尔排序

1 思路
希尔排序也成为“缩小增量排序”,其基本原理是,现将待排序的数组元素分成多个子序列,使得每个子序列的元素个数相对较少,
然后对各个子序列分别进行直接插入排序,待整个待排序列“基本有序”后,最后在对所有元素进行一次直接插入排序。因此,我们
要采用跳跃分割的策略:将相距某个“增量”的记录组成一个子序列,这样才能保证在子序列内分别进行直接插入排序后得到的结果
是基本有序而不是局部有序。希尔排序是对直接插入排序算法的优化和升级。

2 代码demo  
private static void shellSort(int[] array) {
    // 1 特殊情况的预处理
    if (null == array || array.length == 1) {
        return;
    }
    // 2 逐位放到正确的位置上
    int tmp;
    int j;
    for (int count = array.length / 2; count > 0; count /= 2) {  // 缩小增量
        for (int i = count; i < array.length; i++) { // 此增量的子数组进行插入排序
            tmp = array[i];
            for (j = i - count; j >= 0; j -= count) {  // 元素逐步插入到正确的位置
                if (array[j] <= tmp) {  // 找到正确的位置就停止
                    break;
                }
                array[j + count] = array[j]; // 不是正确的位置时,元素向后移动
            }
            // 3 把你存放到正确位置
            array[j + count] = tmp;
        }
    }
}

3 快速排序

1 思路
(每次排好一个元素的位置) 以某个元素为基准值,不大于基准值的元素放在它左面,
大于基准值的元素放在它右面.这样基准值的位置就正确了.然后基准值的左右两边
重复上面的操作.


2 代码demo
public static void sort(int[] arr, int left, int right) {
	//递归停止条件
	if (left>=right) {
		return;
	}

	// 初始化
	int base = arr[left];  // 挖出第一个坑(以最左边的元素为基准)
	int i = left;
	int j = right;

	// 循环填坑
	while (i < j) {
		// 从右边找一个比基准小的填充左边的坑
		while (i < j && arr[j] > base) {
			j--;
		}
		arr[i] = arr[j];

		// 从左边找一个比基准大的填充右边的坑
		while (i < j && arr[i] <= base) {
			i++;
		}
		arr[j] = arr[i];
	}
	
	// 填充最后一个坑
	arr[i]=base;
	
	// 递归调用
	sort(arr, left, i-1);
	sort(arr, i+1, right);
}    

4 归并排序

private static void mergeSort(int[] array) {
    if (null == array || array.length == 1) {
        return;
    }
    mergeSort2(array, 0, array.length - 1);
}


private static void mergeSort2(int[] array, int z, int y) {
    if (z >= y) {
        return;
    }

    int m = (z + y) / 2;
    mergeSort2(array, z, m);
    mergeSort2(array, m + 1, y);
    merge(array, z, m, y);
}


// 利用两个临时的桶暂存两个分区的数据,两个桶中的数据有序的放回原数组.
private static void merge(int[] array, int z, int m, int y) {
	// 定义两个临时桶
    int[] a = new int[m - z + 1];
    int[] a2 = new int[y - m];

	// 原数组元素复制到临时桶
    System.arraycopy(array, z, a, 0, a.length);
    System.arraycopy(array, m + 1, a2, 0, a2.length);

	// 有序从临时桶取数放入到原数组
    int x = 0;
    int x2 = 0;
    while (x < a.length && x2 < a2.length) {
        if (a[x] < a2[x2]) {
            array[z++] = a[x++];
        } else {
            array[z++] = a2[x2++];
        }
    }
    // 桶1的剩余数据放入原数组
    while (x < a.length) {
        array[z++] = a[x++];
    }
    // 桶2的剩余数据放入原数组
    while (x2 < a2.length) {
        array[z++] = a2[x2++];
    }
	
}

5 选择排序

1 思路
找到最小元素的索引位置,和第一个索引上的元素互换; 找到次最小元素的索引位置,
和第二个索引上的元素互换;重复上述操作到结束.

2 代码demo
private static void selectSort(int[] array) {
	// 特殊情况处理
    if (null == array || array.length == 1) {
        return;
    }

	// 逐渐寻找最小元素放到合适位置
    int index;
    for (int i = 0; i < array.length-1; i++) {
        index = i;
        for (int j = i + 1; j < array.length; j++) {
            if (array[index] > array[j]) {
                index = j;
            }
        }
        if (index != i) {
            int temp = array[i];
            array[i] = array[index];
            array[index] = temp;
        }
    }
}

6 冒泡排序

1 思路
相邻元素两两比较, 大的向后移动, 直到length-1冒泡或全局有序标记位flag成立.


2 代码demo
private static void maoPaoSortort(int[] array) {
    // 特殊情况处理
    if (null == array || array.length == 1) {
        return;
    }

    int temp;
    boolean flag = true; // 判断是否能提前结束的标记位
    for (int i = 0; i < array.length - 1; i++) {
        // 第i+1次冒泡
        for (int j = 0; j < array.length - 1 - i; j++) {
            if (array[j] >= array[j + 1]) {
                temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
                flag=false;
            }
        }
        
        // 判断是否能提前结束排序
        if(flag){
            break;
        }else {
            flag=true;
        }
        
    }
    
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值