大厂算法刷题(一)


注:题目和解答均来自互联网,侵删

题目1

给定一个有序数组arr,代表坐落在X轴上的点。给定一个正数K,代表绳子的长度。返回绳子最多压中几个点?即使绳子边缘处盖住点也算盖住在这里插入图片描述
int arr[1,4,9,10,20,21]
length = 10

一、常规思路:穷举法。O(N^2)

  1. 双层for循环,遍历每个节点,判断两个节点之前包含的节点数。
  2. 代码思路:
i = 0 ,j = 0 ,中间变量temp(记录节点数)。j ++,temp ++,当arr[j] - arr[i] > length 时 i ++ ,temp = 0

二、优化思路:贪心算法。O(Nlog(N))

  1. 假设有个长度为10的绳子,每次尾部都会落到节点上,那么长度能盖到的节点就是对应最多的点数量。贪心:绳子的末端没必要放到一个不存在的点的位置。判断绳子所在末尾点n,往前的10的长度,存在多少大于n-10的节点,有序数组的查找,可使用二分查找。
    在这里插入图片描述
  2. 代码思路:
	public static int maxPoint1(int[] arr, int L) {
		int res = 1;
		for (int i = 0; i < arr.length; i++) {
			int nearest = nearestIndex(arr, i, arr[i] - L);
			res = Math.max(res, i - nearest + 1);
		}
		return res;
	}

	public static int nearestIndex(int[] arr, int R, int value) {
		int L = 0;
		int index = R;
		while (L <= R) {
			int mid = L + ((R - L) >> 1);
			if (arr[mid] >= value) {
				index = mid;
				R = mid - 1;
			} else {
				L = mid + 1;
			}
		}
		return index;
	}

三、进阶思路。窗口算法。O(N)

  1. 设置两个指针,i,j,初始为0。尾指针向后移动,直到尾指针和头指针的差距大于10时,记录移动的次数。然后头指针向后移动,次数-1,同时尾指针继续向后移动,直到尾指针和头指针的差距大于10时。依次循环记录节点数,取最大。
    在这里插入图片描述
  2. 代码思路:
    1. 代码思路:
    public static int maxPoint2(int[] arr, int L) {
        int left = 0;       //头指针
        int right = 0;      //尾指针
        int N = arr.length; //数组长度
        int max = 0;        //最大节点数
        while (left < N) {  //头指针小于数组长度
            //尾指针小于数组长度,两个指针的差小于绳子的长度。
            while (right < N && arr[right] - arr[left] <= L) {
                right++;
            }
            //返回最大节点数
            max = Math.max(max, right - (left++));
        }
        return max;
    }

题目二

给定一个文件目录的路径,写一个函数统计这个目录下所有的文件数量并返回隐藏文件也算,但是文件夹不算

可以将其理解为一个树,如下如,矩形表示文件夹,椭圆表示文件。那么下面就是树的遍历一般分为深度优先和广度优先。
在这里插入图片描述

一、思路1:深度遍历

  1. 一般使用栈的方式处理深度优先算法。
  2. 将A放入栈中,判断A是否为文件夹,是则将A弹出,将A下面的文件或者文件夹全部放入栈中,那么栈中的数据为B,1,C。
  3. 判断C是否为判断C是否为文件夹,是则将C弹出并将C下面的文件或者文件夹全部放入栈中,那么栈中的数据为B,1,4,D。
  4. 判断D是否为判断D是否为文件夹,是则将D弹出并将D下面的文件或者文件夹全部放入栈中,那么栈中的数据为B,1,4,5,6。
  5. 依次判断栈中的数据,弹出栈是判断为文件则计数加1。
  6. 直到栈为空,返回计数。
public class Code02_CountFiles {

	// 注意这个函数也会统计隐藏文件
	public static int getFileNumber(String folderPath) {
		File root = new File(folderPath);
		if (!root.isDirectory() && !root.isFile()) {
			return 0;
		}
		if (root.isFile()) {
			return 1;
		}
		Stack<File> stack = new Stack<>();
		stack.add(root);
		int files = 0;
		while (!stack.isEmpty()) {
			File folder = stack.pop();
			for (File next : folder.listFiles()) {
				if (next.isFile()) {
					files++;
				}
				if (next.isDirectory()) {
					stack.push(next);
				}
			}
		}
		return files;
	}

	public static void main(String[] args) {
		// 你可以自己更改目录
		String path = "C:\";
		System.out.println(getFileNumber(path));
	}

}

二、思路2:广度遍历

  1. 一般使用队列的方式处理深度优先算法。
  2. 将A放入队列中,判断A是否为文件夹,是则将A弹出,将A下面的文件或者文件夹全部放入队列的末尾中,那么队列中的数据为才C,1,B。
  3. 判断B是否为判断B是否为文件夹,是则将B弹出并将B下面的文件或者文件夹全部放入队列中,那么栈中的数据为3,2,C,1。
  4. 判断D是否为判断1是否为文件夹,是则将1弹出并将1下面的文件或者文件夹全部放入栈中,那么栈中的数据为3,2,C。
  5. 依次判断队列中的数据,弹出队列是判断为文件则计数加1。
  6. 直到队列为空,返回计数。

题目三

一个数组中只有两种字符’G’和’B’,想让所有的G都放在左侧,所有的B都放在右侧但是只能在相邻字符之间进行交换操作,返回至少需要交换几次
如:GBGBGBGBGB

思路:贪心算法

假设G需要在B的左边,那么第一个出现G应该放到第一个位置,第二个出现的G应该放到第二个位置,依次类推。

	public static int minSteps2(String s) {
		if (s == null || s.equals("")) {
			return 0;
		}
		char[] str = s.toCharArray();
		int step1 = 0;
		int gi = 0;
		for (int i = 0; i < str.length; i++) {
			if (str[i] == 'G') { // 当前的G,去左边   方案1
				step1 += i - (gi++);
			}
		}
		return step1;
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值