騰訊筆試題


1. 解壓縮字符串

  由內至外還原字符串並替換

 1 package Exe1;
 2 
 3 import java.util.Collections;
 4 import java.util.Scanner;
 5 
 6 /**
 7  * @author zzm
 8  * @data 2020/4/10 18:16
 9  * 小Q想要給他的朋友發送一個神秘字符串,但是他發現字符串的過於長了,於是小Q發明了一種壓縮算法對字符串中重復的部分進行了壓縮,
10  * 對於字符串中連續的m個相同字符串S將會壓縮為[m|S](m為一個整數且1<=m<=100),例如字符串ABCABCABC將會被壓縮為[3|ABC],現在小Q的同學收到了小Q發送過來的字符串,你能幫助他進行解壓縮么?
11 輸入描述:
12 輸入第一行包含一個字符串s,代表壓縮后的字符串。
13 S的長度<=1000;
14 S僅包含大寫字母、[、]、|;
15 解壓后的字符串長度不超過100000;
16 壓縮遞歸層數不超過10層;
17 
18 輸出描述:
19 輸出一個字符串,代表解壓后的字符串。
20  */
21 public class Compress {
22     public static void main(String[] args) {
23         Scanner scanner = new Scanner(System.in);
24         String str = scanner.next();
25         scanner.close();
26         StringBuilder s = new StringBuilder(str);
27         char c;
28 
29         for (int i = 0; i < s.length(); i++) {
30             c = s.charAt(i);
31             if (c == ']') {
32                 int left = i, mid;
33                 while (s.charAt(--left) != '|') ;
34                 mid = left;
35                 while (s.charAt(--left) != '[') ;
36                 int times = Integer.parseInt(s.substring(left + 1, mid));
37                 String newStr = s.substring(mid + 1, i);
38                 newStr = String.join("", Collections.nCopies(times, newStr));
39 
40                 s.replace(left,i+1,newStr);
41                 i = left;
42             }
43         }
44         System.out.println(s);
45     }
46 }

 2. 逛街看樓問題

  利用棧縮短時間: 

      當前樓往左看,比左邊樓低則能比處在左邊樓多看一座,否則拆(直到左邊樓比當前樓高);

      當前樓往右看,比右邊樓低則能比處在右邊樓多看一座,否則拆(直到右邊樓比當前樓高)。

package Exe1;

import java.util.Scanner;
import java.util.Stack;

/**
 * @author zzm
 * @data 2020/4/10 22:31
 * 小Q在周末的時候和他的小伙伴來到大城市逛街,一條步行街上有很多高樓,共有n座高樓排成一行。
 * 小Q從第一棟一直走到了最后一棟,小Q從來都沒有見到這么多的樓,所以他想知道他在每棟樓的位置處能看到多少棟樓呢?
 * (當前面的樓的高度大於等於后面的樓時,后面的樓將被擋住)
 * <p>
 * 輸入第一行將包含一個數字n,代表樓的棟數,接下來的一行將包含n個數字wi(1<=i<=n),代表每一棟樓的高度。
 * 1<=n<=100000;
 * 1<=wi<=100000;
 * <p>
 * 輸出一行,包含空格分割的n個數字vi,分別代表小Q在第i棟樓時能看到的樓的數量。
 */
public class HangStreet {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) nums[i] = scanner.nextInt();
        scanner.close();
        int totle;

        Stack<Integer> lefts = new Stack<>();
        Stack<Integer> rights = new Stack<>();

        int[] a = new int[n];
        int[] b = new int[n];

        for (int i = 0, j = n - 1; i < n && j >= 0; i++, j--) {
       //i位置往左看能看到的樓 a[i]
= lefts.size();
       //j位置往右看能看到的樓 b[j]
= rights.size(); while (!lefts.isEmpty() && lefts.peek() <= nums[i]) lefts.pop(); while (!rights.isEmpty() && rights.peek() <= nums[j]) rights.pop(); lefts.push(nums[i]); rights.push(nums[j]); } for (int i = 0; i < n; i++) { totle = a[i] + b[i] + 1; if (i == n - 1) System.out.print(totle); else System.out.print(totle + " "); } } }

 3. 最短假期

package Algorithm;

        import java.util.Arrays;
        import java.util.Scanner;

        import static java.lang.Math.min;


/**
 * @author zzm
 * @data 2020/4/15 21:48
 * 由於業績優秀,公司給小Q放了 n 天的假,身為工作狂的小Q打算在在假期中工作、鍛煉或者休息。
 * 他有個奇怪的習慣:不會連續兩天工作或鍛煉。只有當公司營業時,小Q才能去工作,只有當健身房營業時,小Q才能去健身,小Q一天只能干一件事。
 * 給出假期中公司,健身房的營業情況,求小Q最少需要休息幾天。
 * <p>
 * 輸入描述:
 * 第一行一個整數 n(1≤n≤100000) 表示放假天數
 * 第二行 n 個數 每個數為0或1,第 i 個數表示公司在第 i 天是否營業
 * 第三行 n 個數 每個數為0或1,第 i 個數表示健身房在第 i 天是否營業
 * (1為營業 0為不營業)
 * 輸出描述:
 * 一個整數,表示小Q休息的最少天數
 */
public class MinRest {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] works = new int[n];
        int[] exes = new int[n];
        for (int i = 0; i < n; i++) works[i] = scanner.nextInt();
        for (int i = 0; i < n; i++) exes[i] = scanner.nextInt();
        scanner.close();

        //0 for rest, 1 for work, 2 for exe
        int[][] dp = new int[2][3];

        for (int i = 0; i < n; i++) {
            if (works[i] == 1) dp[1][1] = min(dp[0][0], dp[0][2]);
            else dp[1][1] = Integer.MAX_VALUE;

            if (exes[i] == 1) dp[1][2] = min(dp[0][0], dp[0][1]);
            else dp[1][2] = Integer.MAX_VALUE;

            dp[1][0] = min(dp[0][0], min(dp[0][1], dp[0][2])) + 1;

            for (int j = 0; j < 3; j++) dp[0][j] = dp[1][j];
        }
        System.out.println(min(dp[1][0], min(dp[1][1], dp[1][2])));
    }
}

 4. 爭奪視野

(此題通過 60%;超時,待改正)

import java.util.Arrays;
import java.util.Scanner;

/**
 * @author zzm
 * @data 2020/4/15 22:30
 * 小Q在進行一場競技游戲,這場游戲的勝負關鍵就在於能否能爭奪一條長度為L的河道,即可以看作是[0,L]的一條數軸。
 * 這款競技游戲當中有n個可以提供視野的道具−真視守衛,第i個真視守衛能夠覆蓋區間[xi,yi]。現在小Q想知道至少用幾個真視守衛就可以覆蓋整段河道。
 * <p>
 * 輸入描述:輸入包括n+1行。
 * 第一行包括兩個正整數n和L(1<=n<=105,1<=L<=109)
 * 接下來的n行,每行兩個正整數xi,yi(0<=xi<=yi<=109),表示第i個真視守衛覆蓋的區間。
 * <p>
 * 輸出描述:
 * 一個整數,表示最少需要的真視守衛數量, 如果無解, 輸出-1。
 * 示例1
 * 輸入
 * 4 6
 * 3 6
 * 2 4
 * 0 2
 * 4 7
 * 輸出
 * 3
 */
public class MinEye {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int l = scanner.nextInt();
        int[][] eyes = new int[n][2];
        for (int i = 0; i < n; i++) {
            eyes[i][0] = scanner.nextInt();
            eyes[i][1] = scanner.nextInt();
        }
        scanner.close();

        Arrays.sort(eyes, (a, b) -> a[0] - b[0]);
        int start = 0, res = 0, index=0;
        while (start < l) {
            int temp = start;
       //當前視野需要左邊<=start 右邊大於start, 並找到可覆蓋當前最左邊視野的 最大右邊
for (int i = index; i < n; i++) if (eyes[i][0] <= temp && eyes[i][1] > start) { index = i; start = eyes[i][1]; } if (temp == start) { System.out.println(-1); return; } res++; } System.out.println(res); } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM