Table of contents
[Title description][Baidu original interview question]
[Problem description insert interval]
[Problem description: pure coding problem]
[The question describes the maximum path sum on a tree]
【Case 1】
[Title description]
[Analysis of ideas]
Create an array, arr[i] represents the farthest position that a non-repeating character substring can reach when it ends at position i. Then for the number at position i+1, its first bottleneck is the farthest position that position i can reach. The second bottleneck is the position where the number at position i+1 last appeared. Then the closest of these two positions is the farthest position that the i+1 position can reach.
【Code】
import java.util.Scanner;
/**
* @ProjectName: study3
* @FileName: Ex1
* @author:HWJ
* @Data: 2023/9/12 12:41
*/
public class Ex1 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String express = input.next();
char[] str = express.toCharArray();
int[] res = new int[str.length];
for (int i = 0; i < str.length; i++) {
res[i] = -1; // 初始话数组.
}
for (int i = 1; i < str.length; i++) {
res[i] = res[i - 1];
for (int j = i - 1; j > res[i - 1]; j--) {
if(str[j] == str[i]){
res[i] = j;
break;
}
}
}
int max = Integer.MIN_VALUE;
int maxIndex = -1;
for (int i = 0; i < str.length; i++) {
if(i - res[i] > max){
max = i - res[i];
maxIndex = res[i];
}
}
String ans = "";
for (int i = maxIndex + 1; i < maxIndex + 1 + max; i++) {
ans += str[i];
}
System.out.println(ans);
}
}
【Case 2】
[Title description][Baidu original interview question]
[Analysis of ideas]
We first make two functions, f function and g function. The f function indicates how many strings have a length of len, and the g function indicates how many strings start with the i character and have a length of len. Then we consider a certain general situation to illustrate the role of these two functions.
Suppose a certain string is fmp.
Their lexicographic size must be the number of length 1 + the number of length 2 + the number of length 3 at the beginning of ae. (You can order the first letter f at this time.) + gl starts with a number of length 2. (You can order the second character m at this time). + no number with length 1 (Set the third character at this time, if there are no more characters in the sequence, stop, and add 1 after stopping) + 1.
In this way, the lexicographic order of the requested string is obtained.
【Code】
import java.util.Scanner;
/**
* @ProjectName: study3
* @FileName: Ex2
* @author:HWJ
* @Data: 2023/9/12 14:56
*/
public class Ex2 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String str = input.next();
int ans = kth(str);
System.out.println(ans);
}
// g(int i, int len)函数代表以字母i开头时,长度为len的字符串有多少个。
// i = 1代表a,, i = 26代表z
public static int g(int i, int len){
int sum = 0;
if(len == 1){
return 1;
}
for (int j = i + 1; j <= 26; j++) {
sum += g(j, len - 1);
}
return sum;
}
// f(int len) 函数表示长度为len的字符串有多少个。
public static int f(int len){
int sum = 0;
for (int i = 1; i <= 26; i++) {
sum += g(i, len);
}
return sum;
}
public static int kth(String s){
int sum = 0;
char[] str = s.toCharArray();
int len = str.length;
for (int i = 1; i < len; i++) {
sum += f(i);
}
int first = str[0] - 'a' + 1; // 第一个字符
for (int i = 1; i < first; i++) {
sum += g(i, len);
}
int pre = first;
for (int i = 1; i < len; i++) {
int cur = str[i] - 'a' + 1;
for (int j = pre + 1; j < cur; j++) {
sum += g(j, len - i);
}
pre = cur;
}
return sum + 1;
}
}
【Case 3】
[Problem description insert interval]
Inserting a range gives a non-overlapping list of ranges sorted by their start and endpoints. When inserting a new range into a list, you need to make sure that the ranges in the list are still ordered and do not overlap (merging ranges if necessary).
[Analysis of ideas]
Find all intervals that overlap with the new interval, and then merge these intervals with the new interval.
The condition for judging whether two intervals a and b overlap. When the areas of the two intervals overlap, it can be expressed as a.start <= b.end && b.start <= a.end
【Code】
import java.util.ArrayList;
import java.util.List;
/**
* @ProjectName: study3
* @FileName: Ex3
* @author:HWJ
* @Data: 2023/9/12 15:47
*/
public class Ex3 {
public static void main(String[] args) {
}
public static List<Interval> insert(List<Interval> list, Interval newInterval){
List<Interval> result = new ArrayList<>();
int i = 0;
while (i < list.size() && list.get(i).end < newInterval.start){
result.add(list.get(i++));
}
// 当两个区间的区域重叠时 可以表示为 a.start <= b.end && b.start <= a.end
while(i < list.size() && list.get(i).start <= newInterval.end){
newInterval.start = Math.min(newInterval.start, list.get(i).start);
newInterval.end = Math.max(newInterval.end, list.get(i++).end);
}
result.add(newInterval);
while (i < list.size()){
result.add(list.get(i++));
}
return result;
}
public static class Interval{
public int start;
public int end;
public Interval(int start, int end) {
this.start = start;
this.end = end;
}
}
}
【Case 4】
[Problem description: pure coding problem]
Given an array of all positive numbers, each number represents the distance of a displacement, and the order of the displacements is upper right, left, lower, right..., then if a certain displacement goes through the place where the previous displacement passed, then Returns true, or false if the location has not been visited.
[Analysis of ideas]
First analyze all possible collision situations on paper, and then simplify these rules logically.
【Code】
package IntermediateLift9;
/**
* @ProjectName: study3
* @FileName: Ex4
* @author:HWJ
* @Data: 2023/9/12 20:43
*/
public class Ex4 {
public static void main(String[] args) {
}
public static boolean isSelfCrossing(int[] arr) {
if (arr.length < 4) {
return false;
}
if ( (arr[2] <= arr[0] && arr[3] >= arr[1])
||
(arr.length > 4 && ((arr[3] <= arr[1] && arr[4] >= arr[2]) ||
(arr[3] == arr[1] && arr[0] + arr[4] >= arr[2])))){
return true;
}
for (int i = 5; i < arr.length; i++) {
if (arr[i - 1] <= arr[i - 3]
&& ((arr[i] >= arr[i - 2]) || (arr[i - 2] >= arr[i -4]
&& arr[i - 5] + arr[i - 1] >= arr[i * 3] && arr[i - 4] + arr[i] >= arr[i - 2]))){
return true;
}
}
return false;
}
}
【Case 5】
[Title description]
There is a string str, and then there is a string array, which stores multiple strings. Each string in the array can be used multiple times. Please tell me the number of ways to use these strings to splice the string str.
[Analysis of ideas]
The simple idea is recursion. (It’s a simple loop traversal, you can understand it by looking at the code)
To speed up the idea, create a prefix tree for all the strings in this array. When looking for a substring in the prefix tree, you can use the end attribute of the node to determine whether it is an available substring in the array. Stop looking when you find the end.
【Code】
import java.util.Arrays;
import java.util.HashSet;
/**
* @ProjectName: study3
* @FileName: Ex5
* @author:HWJ
* @Data: 2023/9/12 21:59
*/
public class Ex5 {
public static void main(String[] args) {
}
public static int ways1(String str, String[] arr) {
HashSet<String> strings = new HashSet<>(Arrays.asList(arr));
return f1(str, 0, strings);
}
public static int f1(String str, int index, HashSet<String> set) {
int ans = 0;
for (int end = index; end < str.length(); end++) {
// 这个生成子字符串的行为其实是一个遍历行为,所以花费也为O(str,length())
String subStr = str.substring(index, end + 1);
if (set.contains(subStr)) {
// hashSet 查询时使用的是hash函数确定所寻找数据的哈希值。
// 如果寻找数据为普通数据结构,则查找花费为O(1)
// 但是如果寻找数据为String, 则需要算出数据的所有位信息,然后合并为哈希值,花费为O(str.length())
ans += f1(str, end + 1, set);
}
}
return ans;
}
public static class Node {
public Node[] nexts;
public boolean end;
public Node() {
this.nexts = new Node[26];
this.end = false;
}
}
public static int ways2(String str, String[] arr) {
Node head = new Node();
Node cur = head;
for (String s : arr) {
char[] strs = s.toCharArray();
for (int i = 0; i < strs.length; i++) {
Node node = new Node();
if (cur.nexts[strs[i] - 'a'] == null){
cur.nexts[strs[i] - 'a'] = node;
}
cur = node;
}
cur.end = true;
cur = head;
}
return f2(str.toCharArray(), 0, head);
}
// 这里使用前缀树的方法加速,在遍历子字符串的同时判断其是否存在。
public static int f2(char[] str, int index, Node head) {
int ans = 0;
Node cur = head;
for (int end = index; end < str.length; end++) {
if (cur.nexts[str[end] - 'a'] == null){
break;
}
cur = cur.nexts[str[end] - 'a'];
if (cur.end){
ans += f2(str, end + 1, head);
}
}
return ans;
}
}
【Case 6】
[The question describes the maximum path sum on a tree]
You can go from any node in a tree to any other node (limited to nodes that can only go down or not). Find the path and the largest path among all these paths.
[Analysis of ideas]
For any node node, there are two situations.
(1) The maximum path, starting from node.
a. The maximum path is the node itself.
b. The maximum path is node and the sum of the maximum paths starting from node.left
c. The maximum path is node and the sum of the maximum paths starting from node.right
(2) The maximum path does not start from node.
a. The maximum path is the maximum path that does not start from node.left
b. The maximum path is the maximum path that does not start from node.right
【Code】
/**
* @ProjectName: study3
* @FileName: Ex6
* @author:HWJ
* @Data: 2023/9/12 23:00
*/
public class Ex6 {
public static void main(String[] args) {
}
public static class ReturnData{
public int maxPath;
public int haveMaxPath;
public ReturnData(int maxPath, int haveMaxPath) {
this.maxPath = maxPath;
this.haveMaxPath = haveMaxPath;
}
}
public static class Node{
public int value;
public Node left;
public Node right;
public Node(int value, Node left, Node right) {
this.value = value;
this.left = left;
this.right = right;
}
}
public static int getMax(Node head){
ReturnData data = getMaxWay(head);
return Math.max(data.maxPath, data.haveMaxPath);
}
public static ReturnData getMaxWay(Node node){
if (node == null){
return null;
}
ReturnData left = getMaxWay(node.left);
ReturnData right = getMaxWay(node.right);
// 情况1 最大路径以node出发。
int haveMaxPath = Integer.MIN_VALUE;
if (right != null){
haveMaxPath = Math.max(haveMaxPath, right.haveMaxPath);
}
if (left != null){
haveMaxPath = Math.max(haveMaxPath, left.haveMaxPath);
}
haveMaxPath = Math.max(haveMaxPath, node.value);
// 情况2 最大路径不以node出发
int maxPath = Integer.MIN_VALUE;
if (right != null){
maxPath = Math.max(maxPath, right.maxPath);
}
if (left != null){
maxPath = Math.max(maxPath, left.maxPath);
}
return new ReturnData(maxPath, haveMaxPath);
}
}