左神算法之中级提升(2)

目录

[案例1】

【题目描述】

【思路解析1】

【思路解析2】

【代码实现】

【案例2】

【题目描述】

 【思路解析】

【代码实现】

【案例3】

【题目描述】

 【思路解析】

【代码实现】

【案例4】

【题目描述】今日头条2018面试题 第四题

【输入描述】

【思路解析】

【代码实现】

【案例5】

【题目描述】

 【思路解析】

【代码实现】

【案例6】

【题目描述】

【思路解析】

【代码描述】

【案例7】

【题目描述】

 【思路解析】

【代码实现】

【案例8】

【题目描述】

 【思路解析】

【代码实现】

 【改为动态规划】

【案例9】

【题目描述】

【思路解析】

【代码实现】

【案例10】

【题目描述】

【思路解析】

 【代码实现】

【案例11】

【题目描述】

【思路解析】

【代码实现】


[案例1】

【题目描述】

给定一个非负整数n,代表二叉树的节点个数。返回能形成多少种不同的二叉树结构。

【思路解析1】

如果n小于0,返回0,如果n为1,可以形成一个空二叉树结构,如果n为1也可以形成一种二叉树结构,如果n为2,可以形成两种二叉树结构。对于其余普遍情况来说,总的情况为,(1)左子树没有节点,右子树有n-1个节点。(2)左子树一个节点,右子树n-2个节点.......(n)左子树n-1个节点,右子树无节点。这所有情况的总和。当一个子树节点超过二时,有可以把它作为主树来使用递归。

【思路解析2】

通过暴力递归改为动态规划。

【代码实现】

/*** @ProjectName: study3* @FileName: Ex1* @author:HWJ* @Data: 2023/7/10 8:10*/
public class Ex1 {public static void main(String[] args) {System.out.println(dpWays(3));}public static int ways(int n) {return process(n);}public static int process(int n) {if (n < 0) {return 0;}if (n == 0) {return 1;}if (n == 1) {return 1;}if (n == 2) {  // 这都是baseCase条件return 2;}int res = 0;for (int l = 0; l <= n - 1; l++) { // 按照策略算总和int left = process(l); // 进行暴力递归int right = process(n - l - 1);res += left * right;}return res;}public static int dpWays(int n) {if (n < 0) {return 0;}if (n < 2){return 1;}int[] dp = new int[n + 1];dp[0] = 1; // 根据baseCase初始化for (int i = 1; i <= n; i++) { // 这里通过i来求不同节点的情况数。for (int j = 0; j < i; j++) {dp[i] += dp[j] * dp[i - j - 1]; // 通过递归改为动态规划}}return dp[n];}}

【案例2】

【题目描述】

 【思路解析】

如何找到需要添加几个括号,首先我们要明白如何判断它是否是一个完整的括号字符串。

(1)先分析如何判断它是否是一个完整的括号字符串,使用一个变量count,当遍历到左括号时++,当遍历到右括号--,当在某个时刻时,如果count<0则不是一个完整字符串。如果遍历到最后,count==0,则是一个完整字符串。

(2)判断它需要添加多少个括号,使用变量count和ans,当遍历到左括号时count++,当遍历到右括号(1)如果count==0,此时需要添加左括号,ans++,(2)如果count>0,此时count--。遍历到最后,count>0,表示需要添加右括号,所以返回ans+count。

【代码实现】

/*** @ProjectName: study3* @FileName: Ex2* @author:HWJ* @Data: 2023/7/10 9:19*/
public class Ex2 {public static void main(String[] args) {}public static boolean isComplete(String s) {char[] chars = s.toCharArray();int count = 0;for (int i = 0; i < chars.length; i++) {if (chars[i] == '(') {count++;}else {count--;}if (count < 0) { // 如果出现任意时候,右括号比左括号,这时一定不能构成完整括号字符串return false;}}return count == 0;// 结束后count必须等于0}public static int needRight(String s) {char[] chars = s.toCharArray();int count = 0;int ans = 0;for (int i = 0; i < chars.length; i++) {if (chars[i] == '(') {count++;}else {if (count == 0) {ans++;} else {count--;}}}return ans + count;}}

【案例3】

【题目描述】

 【思路解析】

因为要求去重,所有可以HashSet结构来做,然后再遍历每个元素num,然后查询num+k是否存在,这样就可以找到每个去重数字对了。 

【代码实现】

import java.util.HashSet;/*** @ProjectName: study3* @FileName: Ex3* @author:HWJ* @Data: 2023/7/10 10:04*/
public class Ex3 {public static void main(String[] args) {}public static int k_num(int[] arr, int k) {HashSet<Integer> set = new HashSet<>();for (int i = 0; i < arr.length; i++) {set.add(arr[i]);}int count = 0;for (Integer i : set) {if (set.contains(i + k)) {count++;}}return count;}
}

【案例4】

【题目描述】今日头条2018面试题 第四题

给一个包含n个整数元素的集合a,一个包含m个整数元素的集合b。
定义magic操作为,从一个集合中取出一个元素,放到另一个集合里,切操作过后每个集合的平均值都大于操作前。
注意一下两点:

不可以把一个集合的元素取空,这样就没有平均值了
值为x的元素从集合b取出放入集合a,但集合a中已经有值为x的元素,则a的平均值不变(因为集合元素不会重复),b的平均值可能会改变(因为x被取出了)
问最多可以进行多少次magic操作?

【输入描述】

第一行为两个整数n,m
第二行n个整数,表示集合a中的元素
第三行m个整数,表示集合b中的元素
对于100%的数据,,集合a中元素互不相同,集合b中的元素互不相同。

【思路解析】

对于集合a的平均值假设为avg_a,集合b的平均值假设为avg_b

(1)avg_a==avg_b,无法找到有效值取出

a. 取出a集合中大于avg_a的值,会使a的平均值下降,不满足要求

b. 取出a集合中等于avg_a的值,集合a和b平均值不会变化,不满足要求。

c. 取出a集合中小于avg_a的值,会使b的平均值下降,不满足要求。

(2)avg_a<avg_b,无法找到有效值取出

a. 取出a集合中大于avg_a的值,会使a的平均值下降,不满足要求。

b. 取出a集合中等于avg_a的值,会使b的平均值下降,不满足要求。

c. 取出a集合中小于avg_a的值,会使b的平均值下降,不满足要求。

(3)avg_a>avg_b

a. 取出a集合中大于avg_a的值,会使a的平均值下降,不满足要求。

b. 取出a集合中等于avg_a的值,会使b的平均值上升,但a集合的平均值不会变化,不满足要求。

c. 取出a集合中小于avg_a的值并且大于avg_b的值,会使b的平均值上升,会使avg_a的平均值上升,满足要求。

(c.1) 取出a集合中小于avg_a的值并且大于avg_b的值,这样的值可能有多个,我们应选择这里面中最小的值(并且满足b集合不存在这个值),这样可以使avg_a变大幅度尽可能大,可以avg_b变大的幅度尽可能小。这样差值越大,则选择的值可能会进一步变多。

【代码实现】

import java.util.Arrays;
import java.util.HashSet;/*** @ProjectName: study3* @FileName: Ex4* @author:HWJ* @Data: 2023/7/10 10:46*/
public class Ex4 {public static void main(String[] args) {}public static int times(int[] a, int[] b) {int sumA = 0;for (int i = 0; i < a.length; i++) {sumA += a[i];}int sumB = 0;for (int i = 0; i < b.length; i++) {sumB += b[i];}if (avg(sumA, a.length) == avg(sumB, b.length)) {return 0;}int[] arrMore;int[] arrLess;int moreSize;int lessSize;int sumMore;int sumLess;if (avg(sumA, a.length) > avg(sumB, b.length)) { // 对数组进行预处理arrMore = a;arrLess = b;sumMore = sumA;sumLess = sumB;moreSize = a.length;lessSize = b.length;} else {arrMore = b;arrLess = a;sumMore = sumB;sumLess = sumA;moreSize = b.length;lessSize = a.length;}HashSet<Integer> lessSet = new HashSet<>(); // 将较小平均值的数组创建一个集合,方便查询后面要加入的值是否存在for (int i = 0; i < lessSize; i++) {lessSet.add(arrLess[i]);}Arrays.sort(arrMore); // 对较大平均值的数组进行排序,保证拿出的有效数一定是较小的那个int ops = 0; // 操作数for (int i = 0; i < arrMore.length; i++) {int cur = arrMore[i];if (cur < avg(sumMore, moreSize) &&cur > avg(sumLess, lessSize) &&!lessSet.contains(cur)) { // 按顺序依次拿出较小值sumMore -= cur; // 拿出后对数据进行处理sumLess += cur;moreSize--;lessSize++;lessSet.add(cur);ops++;}}return ops;}public static double avg(int sum, int len) {return (sum * 1.0) / len;}
}

【案例5】

【题目描述】

 【思路解析】

它给出的是一个合法的括号序列,所以我们并不需要验证它是否是完整的括号字符串序列。使用一个遍历count,遇到左括号count++,遇到右括号count--,其中count的最大值就是这个括号字符串序列的深度。

【代码实现】

/*** @ProjectName: study3* @FileName: Ex5* @author:HWJ* @Data: 2023/7/10 11:18*/
public class Ex5 {public static void main(String[] args) {System.out.println(depth("(()(()))"));}public static int depth(String s){if (s == null){return 0;}char[] chars = s.toCharArray();int count = 0;int max =Integer.MIN_VALUE;for (int i = 0; i < chars.length; i++) {if (chars[i] == '('){count++;}else {count--;}max = Math.max(count, max);}return max;}
}

【案例6】

【题目描述】

给你一个字符串其中只包含‘(’和‘)’,找出其中最长的有效括号字符串,并返回这个字符串的长度。

【思路解析】

计算以当前字符作为结尾时,最长有效括号字符串的长度为多少,然后统计其中的最大值。当当前字符为左括号时,以次字符为结尾不可能有左子符。如果当前字符为右括号,它就需要找到前面是否有左括号与其配对。怎么找到前面和它配对的字符在那个位置上,如果当前字符位置为i,我们可以知道i-1位置上有效字符串,则配对位置应该为i-dp[i-1]-1,如果为左括号则配对成功,否则配对失败。

配对成功后,怎么计算当前位置的有效长度:dp[i] = dp[i-1] + 2 + (pre > 0 ? dp[pre - 1] : 0);

【代码描述】

/*** @ProjectName: study3* @FileName: Ex6* @author:HWJ* @Data: 2023/7/10 11:25*/
public class Ex6 {public static void main(String[] args) {}public static int maxLength(String s) {if (s == null || s.equals("")) {return 0;}char[] chars = s.toCharArray();int[] dp = new int[chars.length];int pre = 0;int res = 0;for (int i = 1; i < chars.length; i++) {if (chars[i] == ')') {pre = i - dp[i - 1] - 1;if (pre >= 0 && chars[pre] == '(') {dp[i] = dp[i - 1] + 2 + (pre > 0 ? dp[pre - 1] : 0);}}res = Math.max(res, dp[i]);}return res;}}

【案例7】

【题目描述】

 【思路解析】

构建一个辅助栈,其中按降序的方式进行排序,当原始栈不为空时,弹出元素,如果能按照降序的方式加入辅助栈就直接加入,否则就弹出辅助栈的元素重新加入原始栈,知道满足降序时将次元素加入辅助栈。

【代码实现】


import java.util.Stack;/*** @ProjectName: study3* @FileName: Ex7* @author:HWJ* @Data: 2023/7/10 12:55*/
public class Ex7 {public static void main(String[] args) {Stack<Integer> stack = new Stack<>();stack.add(2);stack.add(9);stack.add(7);stack.add(6);stack.add(4);stack.add(5);stack.add(3);sort(stack);while (!stack.isEmpty()){System.out.println(stack.pop());}}public static void sort(Stack<Integer> stack){Stack<Integer> help = new Stack<>();while (!stack.isEmpty()){int cur = stack.pop();if (help.isEmpty()){help.add(cur);}else {while (!help.isEmpty() && cur > help.peek()){stack.add(help.pop());}help.add(cur);}}while (!help.isEmpty()){stack.add(help.pop());}}}

【案例8】

【题目描述】

 【思路解析】

【代码实现】

/*** @ProjectName: study3* @FileName: NumToStr* @author:HWJ* @Data: 2023/6/12 14:31*/
public class NumToStr {public static void main(String[] args) {}public static int translate(String str){char[] charArray = str.toCharArray();return process(charArray, 0);}public static int process(char[] str, int i){if ( i == str.length){ // 如果已经把所有的都决定完了,返回1return 1;}if (str[i] == '0'){ // 如果第i位为0,没法转换,返回0return 0;}if (str[i] == '1'){int res = process(str, i+1);  // i 自己作为单独的部分,后续有多少种方法,if (i+1 < str.length){res += process(str, i+2);// (i 和 i+1) 自己作为单独的部分,后续有多少种方法}return res;}if (str[i] == '2'){int res = process(str, i+1); // i 自己作为单独的部分,后续有多少种方法,if (i+1 < str.length && str[i+1] >= '0' && str[i+1] <= '6'){ // (i 和 i+1) 自己作为单独的部分,后续有多少种方法,res += process(str, i+2);   // 明确要求其不能超过26}return res;}return process(str, i+1);}
}

 【改为动态规划】

/*** @ProjectName: study3* @FileName: Ex8* @author:HWJ* @Data: 2023/7/10 14:32*/
public class Ex8 {public static void main(String[] args) {}public static int dpWays(String s) {if (s.length() == 0) {return 0;}char[] str = s.toCharArray();int N = str.length;int[] dp = new int[N + 1];dp[N] = 1;dp[N - 1] = str[N - 1] == 0 ? 0 : 1;for (int i = N - 2; i >= 0; i--) {if (str[i] == '0') {dp[i] = 0;} else {dp[i] = dp[i + 1];int t = dp[i + 1] + (dp[i] - '0') * 10;if (t <= 26) {dp[i] += dp[i + 2];}}}return dp[0];}}

【案例9】

【题目描述】

【思路解析】

这里使用递归。很简单,详情看代码。

【代码实现】

说明:Node节点的代码很简单,这里懒得给出了。

/*** @ProjectName: study3* @FileName: Ex9* @author:HWJ* @Data: 2023/7/10 14:43*/
public class Ex9 {public static void main(String[] args) {}public static int getMax(Node head){if (head == null){return 0;}return process(head);}public static int process(Node node){int left = node.value;int right = node.value;if (node.right != null){right += process(node.right);}if (node.left != null){left += process(node.left);}return Math.max(left, right);}
}

 

【案例10】

【题目描述】

 

【思路解析】

因为它每行和每列都是有序的,所以遍历从矩阵右上角开始。如果当前位置大于目标值就往左滑动一下,,如果当前位置小于目标值就往下滑动。直到越界了,还没有找到目标值就返回false。

 【代码实现】

/*** @ProjectName: study3* @FileName: Ex10* @author:HWJ* @Data: 2023/7/10 15:12*/
public class Ex10 {public static void main(String[] args) {int[][] matrix = {{1, 5, 9, 10}, {2, 6, 11, 13}, {7, 9, 15, 17}};System.out.println(search(matrix, 7));}public static boolean search(int[][] matrix, int aim) {int N = matrix.length;int M = matrix[0].length;int i = 0;int j = M - 1;while (i >= 0 && i < N && j >= 0 && j < M) {if (matrix[i][j] > aim) {j--;} else if (matrix[i][j] < aim) {i++;} else {return true;}}return false;}
}

【案例11】

【题目描述】

给出一个二维矩阵,每行都只有1和0,并且规定左边全是0,右边全是1,返回含1最多的行号。

如 00011111  或者 0000000 或者 11111111

【思路解析】

从右上角开始,滑动到第一行的第一个1的位置,并记录当前max1(表示目前已知最多1的数量),然后将第一行的行号加入到list中。然后往下滑动,如果此位置是0,就继续往下滑动,如果此位置是1,就参看是否能往左滑动,如果能,则清空list,并重新记录max1和将此行行号加入到list中,如果不能,则把此行行号加入到list中。

【代码实现】

import java.util.LinkedList;/*** @ProjectName: study3* @FileName: Ex11* @author:HWJ* @Data: 2023/7/10 15:32*/
public class Ex11 {public static void main(String[] args) {int[][] matrix = {{0,0,0,0,1,1,1},{0,0,0,1,1,1,1},{0,0,0,0,0,0,1},{0,0,0,1,1,1,1},{1,1,1,1,1,1,1}};LinkedList<Integer> list = search(matrix);for (int i :list) {System.out.println(i);}}public static LinkedList<Integer> search(int[][] matrix) {int N = matrix.length;int M = matrix[0].length;int i = 0;int j = M - 1;LinkedList<Integer> list = new LinkedList<>();while (i >= 0 && i < N && j >= 0 && j < M) {if (j > 0 && matrix[i][j-1] == 1) {if (i != 0) { // 如果向下滑动后能左滑,就清空列表list.clear();}j--;} else{if (i == 0){ //如果此时不能左滑了,此时为第一行,则直接加入,list.add(i+1);}else {if(matrix[i][j] == 1){ // 如果不是第一行,当前位置是1,就加入list.add(i+1);}}i++;}}return list;}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/21744.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

零拷贝是如何实现的

零拷贝是如何实现的 零拷贝&#xff08;Zero-copy&#xff09;是一种优化技术&#xff0c;用于在数据传输过程中减少数据的拷贝次数&#xff0c;从而提高数据传输的效率和性能。传统的数据传输涉及多次内存拷贝操作&#xff0c;而零拷贝通过减少或避免这些拷贝操作来实现性能优…

​LeetCode解法汇总​979. 在二叉树中分配硬币

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a;力扣 描述&#xff1a; 给定一个有 N 个结点的二叉树的根结点 root&#xff0c;树中的每个结点上都对应…

VMware ESXi 7.0 U3n macOS Unlocker OEM BIOS 集成网卡驱动和 NVMe 驱动 (集成驱动版)

VMware ESXi 7.0 U3n macOS Unlocker & OEM BIOS 集成网卡驱动和 NVMe 驱动 (集成驱动版) ESXi 7 U3 标准版集成 Intel 网卡、USB 网卡 和 NVMe 驱动 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-esxi-7-u3-sysin/&#xff0c;查看最新版。原创作品&#x…

力扣 55. 跳跃游戏

题目来源&#xff1a;https://leetcode.cn/problems/jump-game/description/ C题解&#xff08;来源代码随想录&#xff09;&#xff1a;不断更新可覆盖范围&#xff0c;能达到最后一个元素即返回true&#xff0c;否则返回false。 class Solution { public:bool canJump(vecto…

中国移动光猫设置桥接

网上教程五花八门&#xff0c;有些坑有些行&#xff0c;我试成功了&#xff0c;记录一下方法。 一、流程简述 1. 使用超级管理员账号登录中国移动光猫&#xff0c;设置桥接&#xff0c;并重启 2. 用网线连接路由器和光猫&#xff0c;登录路由器&#xff0c;设置宽带拨号&…

【SAP UI5 控件学习】DAY04 Input组Part IV 完结List组Part I

1.时间选择器Time Picker 和Data Picker类似&#xff0c;Time Picker允许用户选择相应的时间。 它有以下一些比较常用的属性。 value用于显示Input中的时间的值&#xff0c;这个属性只能接受字符串的值&#xff0c;如果是UI5.getInstance()获取到的时间&#xff0c;需要转化成…

Linux文件系统概述

本文已收录至《Linux知识与编程》专栏&#xff01; 作者&#xff1a;ARMCSKGT 演示环境&#xff1a;CentOS 7 文件系统概述 前言正文文件与磁盘磁盘介绍与机械硬盘机械硬盘基础结构机械硬盘数据存储与管理 文件操作的细节创建文件访问文件删除文件恢复文件其他情况 最后 前言 …

力扣 279. 完全平方数

一、题目描述 给你一个整数 n&#xff0c;返回和为 n 的完全平方数的最少数量 。 完全平方数是一个整数&#xff0c;其值等于另一个整数的平方&#xff1b;换句话说&#xff0c;其值等于一个整数自乘的积。例如&#xff0c;1、4、9 和 16 都是完全平方数&#xff0c;而 3 和 …

哪款蓝牙耳机通话清楚,几款拥有通话降噪技术的骨传导耳机分享

嘿&#xff0c;你是音乐爱好者吗&#xff1f;还是热衷于锻炼身体&#xff1f;那么你一定不能错过骨传导耳机&#xff01;这种神奇的耳机通过骨头的振动来传递声音&#xff0c;绝不同于传统的耳道或鼓膜传播方式。你可保持对周围环境的警觉&#xff0c;同时避免对你的听力造成任…

使用chatgpt过funcaptcha验证码3个人学习记录

funcaptcha 验证码3 通过记录 往期验证码&#xff1a;http://t.csdn.cn/ulgXY funcaptcha1 往期验证码&#xff1a;http://t.csdn.cn/3xMnZ funcaptcha2 funcaptcha 那个公司开发的简要介绍&#xff1a; Funcaptcha是由hCaptcha公司开发的一种人机验证系统。hCaptcha是一家位…

Golang学习之结构体和内存对齐、map设计思路

Golang学习之结构体和内存对齐、map设计思路 结构体和内存对齐内存对齐如何确定一个结构体的对其边界 map设计思路哈希表与扩容bmap的结构练习map扩容规则 结构体和内存对齐 cpu要想从内存读取数据&#xff0c;需要通过地址总线&#xff0c;把地址传输给内存&#xff0c;内存准…

从技术出发or从场景出发:大模型开始“路线分化”?

文 | 智能相对论 作者 | 叶远风 大模型时代&#xff0c;厂商们狂奔突袭&#xff0c;技术创新一浪高过一浪。 在这个过程中&#xff0c;先赶上风口做出一个大模型产品&#xff0c;宣传一波、站稳脚跟&#xff0c;再慢慢谈场景应用、价值落地&#xff0c;是很多厂商的做法——…