左神_中级班_02

1.给定一个数组arr,求差值为k的去重数组对

	public static List<List<Integer>> allPair(int[] arr, int k) {
		HashSet<Integer> hashSet=new HashSet<>();
		for (int i = 0; i < arr.length; i++) {
			hashSet.add(arr[i]);
		}
		List<List<Integer>> list=new ArrayList<>();
		for (Integer integer : hashSet) {
//			List<Integer> listZi=new ArrayList<>();
			if(hashSet.contains(integer+k)){
//				listZi.add(integer);
//				listZi.add(integer+k);
				list.add(Arrays.asList(integer,integer+k));
			}
		}
		return list;
	}

	public static void main(String[] args) {
		int[] arr={3,2,5,7,0,0};
		List<List<Integer>> lists = allPair(arr,2);
		System.out.println(lists.toString());
	}

2.给一个包含n个整数元素的集合a, 一个包含m个整数元素的集合b。
定义magic操作为, 从一个集合中取出一个元素, 放到另一个集合里, 且操作过
后每个集合的平均值都大大于于操作前。
注意以下两点:
1) 不可以把一个集合的元素取空, 这样就没有平均值了
2) 值为x的元素从集合b取出放入集合a, 但集合a中已经有值为x的元素, 则a的
平均值不变(因为集合元素不会重复) , b的平均值可能会改变(因为x被取出
了)
问最多可以进行多少次magic操作

解:A avg=100 B avg=50
只能从平均值大的里面选,且必须符合50<x<100的条件,符合条件中要选最小的,且之后要更新A和B的平均值。

	// 请保证arr1无重复值、arr2中无重复值,且arr1和arr2肯定有数字
	public static int maxOps(int[] arr1, int[] arr2) {
		double sum1 = 0;
		for (int i = 0; i < arr1.length; i++) {
			sum1 += (double) arr1[i];
		}
		double sum2 = 0;
		for (int i = 0; i < arr2.length; i++) {
			sum2 += (double) arr2[i];
		}
		if (avg(sum1, arr1.length) == avg(sum2, arr2.length)) {
			return 0;
		}
		int[] arrMore = null;
		int[] arrLess = null;
		double sumMore = 0;
		double sumLess = 0;
		if (avg(sum1, arr1.length) > avg(sum2, arr2.length)) {
			arrMore = arr1;
			sumMore = sum1;
			arrLess = arr2;
			sumLess = sum2;
		} else {
			arrMore = arr2;
			sumMore = sum2;
			arrLess = arr1;
			sumLess = sum1;
		}
		Arrays.sort(arrMore);
		HashSet<Integer> setLess = new HashSet<>();//要判断少的集合中是否有这个元素
		for (int num : arrLess) {
			setLess.add(num);
		}
		int moreSize = arrMore.length;//平均值大的集合还剩多少个数
		int lessSize = arrLess.length;//平均值小的集合还剩多少个数
		int ops = 0;//操作了多少次
		for (int i = 0; i < arrMore.length; i++) {
			double cur = (double) arrMore[i];
			if (cur < avg(sumMore, moreSize) && cur > avg(sumLess, lessSize)
					&& !setLess.contains(arrMore[i])) {
				sumMore -= cur;
				moreSize--;
				sumLess += cur;
				lessSize++;
				setLess.add(cur);
				ops++;
			}
		}
		return ops;
	}

	public static double avg(double sum, int size) {
		return sum / (double) (size);
	}

	public static void main(String[] args) {
		int[] arr1 = { 1, 2, 5 };
		int[] arr2 = { 2, 3, 4, 5, 6 };
		System.out.println(maxOps(arr1, arr2));

	}

3.求一个合法括号字符串的最大深度:count遇到左括号就++,count遇到右括号就–,count的最大值就是最大深度

	public static int maxDeep(String s){
		if(s==null||s.length()==0){
			return 0;
		}
		char[] chars = s.toCharArray();
		int count=0;
		int max=0;
		for (char aChar : chars) {
			if(aChar=='('){
				count++;
				max=Math.max(count,max);
			}else{
				count--;
			}
		}
		return max;
	}

4.给定括号的字符串,返回有效的子串最大长度(知道思路还是未写出)

	public static int maxLength(String str) {
		if (str == null || str.equals("")) {
			return 0;
		}
		char[] chas = str.toCharArray();
		int[] dp = new int[chas.length];
		int pre = 0;
		int res = 0;
		for (int i = 1; i < chas.length; i++) {
			if (chas[i] == ')') {
				pre = i - dp[i - 1] - 1;
				if (pre >= 0 && chas[pre] == '(') {
					dp[i] = dp[i - 1] + 2 + (pre > 0 ? dp[pre - 1] : 0);
				}
			}
			res = Math.max(res, dp[i]);
		}
		return res;
	}

5.给定一个无序栈,排成升序栈,要求只用一个辅助栈 :辅助栈一直保持降序(妨碍降序的元素扔回原栈)

	public static void sort(Stack<Integer> stack){
		Stack<Integer> help = new Stack<Integer>();
		while(!stack.isEmpty()){
			int cur=stack.pop();
			if(help.isEmpty()){
				help.push(cur);
			}else{
				while(!help.isEmpty()&&help.peek()<=cur){
					stack.push(help.pop());
				}
				help.push(cur);
			}
		}
		while(!help.isEmpty()){
			stack.push(help.pop());
		}
	}

代码简化之后:

	public static void sort1(Stack<Integer> stack){
		Stack<Integer> help = new Stack<Integer>();
		while(!stack.isEmpty()){
			int cur=stack.pop();
			while(!help.isEmpty()&&help.peek()<=cur){
				stack.push(help.pop());
			}
			help.push(cur);
		}
		while(!help.isEmpty()){
			stack.push(help.pop());
		}
	}

6.将给定的数转换为字符串,原则如下,1对应a,2对应b,…26对应z,例如12258可以转换为’abbeh’,‘aveh’,‘abyh’,‘lbeh’,‘lyh’,个数为5,编写一个函数,给出可以转换的不同字符串可数
(1)暴力递归
i位置出发多少种有效的:
[i]==‘0’---------0种
[i] != ‘0’---------f(i+1)
[i][i+1] <=26---------f(i+2)

	public static int convertWays(int num) {
		if(num<1){
			return 0;
		}
		return process(String.valueOf(num).toCharArray(),0);
	}

	public static int process(char[] str, int index) {
		if(index==str.length){
			return 1;
		}
		if(str[index]=='0'){
			return 0;
		}
		int res=process(str,index+1);
		if((index+1<str.length)&&((str[index]-'0')*10+str[index+1]-'0')<27){
			res+=process(str,index+2);
		}
		return res;
	}

(2)动态规划

	public static int dpways(int num) {
		if (num < 1) {
			return 0;
		}
		char[] str = String.valueOf(num).toCharArray();
		int[] dp = new int[str.length + 1];
		dp[str.length] = 1;
		dp[str.length - 1] = str[str.length - 1] == '0' ? 0 : 1;
		for (int i = str.length - 2; i >= 0; i--) {
			if (str[i] == '0') {
				dp[i] = 0;
			} else {
				dp[i] = dp[i + 1]
						+ (((str[i] - '0') * 10 + str[i + 1] - '0') < 27 ? dp[i + 2]
								: 0);
			}
		}
		return dp[0];
	}

7.二叉树从根节点到叶子节点路径权值和最大为多少
(1)非套路递归:pre:记录当前节点之前的路径权值和

	public static int maxNum=Integer.MIN_VALUE;
	public static int maxSumFeiTaoLu(Node head){
		processMax(head,0);
		return maxNum;
	}

	private static void processMax(Node node, int pre) {
		if(node.left==null&&node.right==null){
			maxNum=Math.max(maxNum,pre+node.value);//只有到叶子节点才比较计算
		}
		if(node.left!=null){
			processMax(node.left,pre+node.value);
		}
		if(node.right!=null){
			processMax(node.right,pre+node.value);
		}
	}

(2)套路递归:包括当前节点的树的最大路径权值和

	public static int maxSumTaoLu(Node node){
		return processMaxTaoLu(node);
	}
	private static int processMaxTaoLu(Node node){
		if(node.left==null&&node.right==null){
			return node.value;
		}
		int next=Integer.MIN_VALUE;//记录左右子树中最大的权值和(不包括当前节点)
		if(node.left!=null){
			next=processMaxTaoLu(node.left);
		}
		if(node.right!=null){
			next=Math.max(next,processMaxTaoLu(node.right));
		}
		return node.value+next;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值