腾讯823校招笔试翻车经(请大家给点建议)
1. 删第k个链表节点。一开始傻乎乎的按照要求写,发现超时。
import java.util.Scanner;
public class Main {
private static Node deleteNode(Node head, int k) {
Node dum = new Node(0);
dum.next = head;
Node runner = dum;
for (int i = 0; i < k-1; i++) {
runner = runner.next;
}
Node nxt = runner.next.next; // runner.next should be deleted
runner.next = nxt;
return dum.next;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
Node dum = new Node(0);
Node tail = dum;
System.out.println("before running");
for(int i = 0; i < n; i++){
Node cur = new Node(sc.nextInt());
tail.next = cur;
tail = cur;
}
Node h = deleteNode(dum.next, k);
Node runner = dum.next;
while (runner != null) {
System.out.print(runner.val + " ");
runner = runner.next;
}
}
}
class Node {
int val;
Node next;
public Node (int v){
val = v;
}
} 优化成直接输出,还是超时,只能通过75%。浪费了30-40分钟(哭了)。请高人赐教,这题怎么写才能过?
```java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
for(int i = 0; i < k-1; i++){
int val = sc.nextInt();
System.out.print(val + " ");
}
sc.nextInt();
for(int i = k; i < n; i++){
int val = sc.nextInt();
System.out.print(val + " ");
}
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
for(int i = 0; i < k-1; i++){
int val = sc.nextInt();
System.out.print(val + " ");
}
sc.nextInt();
for(int i = k; i < n; i++){
int val = sc.nextInt();
System.out.print(val + " ");
}
}
}
```
2. 给定字符串str,找第k小distinct子串(排序为字典序升序)。
通过测试用例为0。不知道为啥,请高人赐教。
import java.util.*;
public class Main {
static HashSet<String> all = new HashSet();
private static void construct(String str, int start, int len, StringBuilder sb) {
if (sb.length() == len) {
all.add(sb.toString());
return;
}
int buf_len = sb.length();
for (int i = start; i < str.length(); i++) {
sb.append(str.charAt(i));
construct(str, i+1, len, sb);
sb.setLength(buf_len);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int k = sc.nextInt();
int n = str.length();
for (int len = 1; len <= n; len++)
construct(str, 0, len, new StringBuilder());
List<String> res = new ArrayList();
for (String s: all)
res.add(s);
Collections.sort(res);
System.out.println(res.get(k-1));
}
} 3. 给定一个正数,拆成两个非负的数,位数和(每一个数字相加)最大。通过测试用例100%。
import java.util.*;
public class Main {
static HashMap<Long, Long> mem = new HashMap();
private static long getVal(long n){
if (mem.containsKey(n))
return mem.get(n);
long res = 0;
while (n > 0) {
res += n % 10;
n /= 10;
}
mem.put(n, res);
return res;
}
private static long solve(long n) {
if (n <= 18) return n;
long num1 = 9;
long best = 0;
while (n - num1 > 0) {
best = Math.max(best, getVal(num1) + getVal(n - num1));
num1 = num1*10+9;
}
return best;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
for (int t = 0; t < T; t++) {
long n = sc.nextLong();
System.out.println(solve(n));
}
}
} 4. 木板长度高度均为1,黑板可以横着擦,竖着擦。黑板高度由数组表示(输入第二行)。如果木板在擦黑板中间断了,需要重新开始擦。求最小的擦的次数。这题我不会做,当时放弃了。
样例如下
```
//5
//2 2 1 2 1
//5
//2 2 1 2 1
```
需要返回3。
需要返回3。
经过参考@〢ヽ夜╰︶ ̄太美 的代码,考虑如下dp解法。并不保证正确。
public class Main {
public static int paint(int[] arr) {
int n = arr.length;
int highest = 0;
for (int h: arr)
highest = Math.max(highest, h);
// dp[i][j]: the min cost to paint first i blackboards already, height can achieve j
int[][] dp = new int[n+1][highest+1];
for (int j = 1; j <= highest; j++)
dp[0][j] = j;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= highest; j++)
dp[i][j] = n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= highest; j++) {
// paint vertically
int h = Math.min(j, arr[i-1]);
dp[i][h] = Math.min(dp[i][h], dp[i-1][j] + 1);
// paint horizontally
if (arr[i-1] < n) {
int cur = arr[i-1];
if (j >= arr[i-1])
dp[i][cur] = Math.min(dp[i][cur], dp[i-1][j]);
else
dp[i][cur] = Math.min(dp[i][cur], dp[i-1][j] + cur -j);
}
}
}
int res = n;
for (int j = arr[n-1]; j <= highest; j++)
res = Math.min(res, dp[n][j]);
return res;
}
public static void main(String[] args) {
int[] arr = new int[]{2,2,1,2,1};
System.out.println(paint(arr));
}
}
5. 给定字符串str,给定范围[l, r],求子串能拆成最少的回文串的个数。通过测试案例70-90%。不知道还可以怎么优化了,请高人赐教。
import java.util.*;
public class Main {
static HashMap<String, Integer> mem = new HashMap();
private static int splitPa(String key) {
if (mem.containsKey(key))
return mem.get(key);
int n = key.length();
int best = n;
for (int i = 0; i < n; i++) {
String right = key.substring(i);
if (isPa(right)) {
String left = key.substring(0, i);
best = Math.min(best, 1 + splitPa(left));
}
}
mem.put(key, best);
return best;
}
private static boolean isPa(String str) {
int l = 0;
int r = str.length() - 1;
while (l < r) {
if (str.charAt(l) != str.charAt(r))
return false;
l++;
r--;
}
return true;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int Q = sc.nextInt();
mem.put("", 0);
for (int q = 0; q < Q; q++) {
int l = sc.nextInt();
int r = sc.nextInt();
System.out.println(splitPa(str.substring(l-1, r)));
}
}
}
查看7道真题和解析
小天才公司福利 1194人发布