腾讯(Tencent)2022实习笔试算法题

本文解析了腾讯2022实习笔试中的四个算法题目,涉及字符串拼接、数组操作、质数判断、战士阵营分配及股票投资策略。通过实例演示和代码实现,探讨了如何高效处理和排序数字序列,以及如何优化战斗阵营和投资收益。
摘要由CSDN通过智能技术生成

腾讯(Tencent)2022实习笔试算法题

第一题
题目描述:
牛牛有n个长度相等由数字组成的字符串,牛牛将他们一行一行排列在一起,从上到下读数,可以将这n个字符串读出了一些数字字符串,把这些字符串记录下来并排序输出,去掉前导0.
输入描述:
第一行为n,表示由n个字符串。
接下来有n行,每行有一个字符串str。
1<=n<=9
1<str.length<=10^5
输出描述:
输出为一行,表示排序后的数字,每个数字以空格隔开。
示例1:
输入:

3
0123
1234
2345

输出:

12 123 234 345

说明:每一列从上到下读到的数字为012,123,234,345,去掉前导0之后排序结果如上。
示例2:
输入:

4
0000
0101
1011
0111

输出:

10 11 101 111

python代码:

if __name__ =='__main__':
	n  = int(input())
	num = []
	for i in range(n):
		row = input()
		num.append(row)
	r = len(num[0])
	l = len(num)
	end_num = []
	for i in range(len(num[0])):
		s=0
		for j in range(len(num)):
			s+= int(num[j][i])*pow(10,l-j-1)
		end_num.append(s)
	end_num.sort()
	print(end_num)

第二题:
牛牛有一个长度为n的的数组a,数组下标1-n,每次从a中所有下标为非质数的元素进行删除,即ai 且i不为质数,在删除完之后重新排序,不断循环直至剩余一个元素并输出。

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
       // int a[] = new int[]{1,2,3,4};
        int a[] = new int[]{3,1,1,4,5,6};
        Main main = new Main();
        System.out.println(main.getNumber(a));
    }

    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * @param a int整型一维数组
     * @return int整型
     */
    public int getNumber (int[] a) {
        // write code here
        int n = a.length;
        List<Integer> pnums = getZ(n);
        while (n!=1){
            int k = 0;
            for (int i = 0; i < pnums.size() && pnums.get(i)<n; i++) {
                a[k++] = a[pnums.get(i)];
            }
            n = k;
        }
        return a[0];
    }

    public List<Integer> getZ(int n){
        List<Integer> list = new ArrayList<>();
        for (int i = 2; i < n; i++) {
            if(isP(i)){
                list.add(i-1);
            }
        }
      /*  System.out.print("{");
        for (int i = 0; i < list.size()-1; i++) {
            System.out.print(list.get(i)+",");
        }
        System.out.println(list.get(list.size()-1)+"}");*/
        return list;
    }

    public boolean isP(int x){
        for(int i = 2;i < (int)(Math.sqrt(x)+1);i++){
            if(x%i==0){
                return false;
            }
        }
        return true;
    }
}

第三题:
n个战士排成一排,分别编号为1,2,3,…n。战士的战斗力等于他的编号,有一些战士只会进攻,有一些战士只会防守,现在我们要将他们从某个点开始分成两个阵营,假设这个点pos,则编号为1,2,3…pos的战士为第一阵营,pos+1,pos+2…n为第二阵营,假设pos=0时,说明第一阵营没有战士,所有战士在第二阵营。令第一阵营为进攻方,第二个阵营为防守方,假设第一阵营中能够进攻的战士战斗力总和为w,第二个阵营中能够防守的战士战斗力总和为v,我们希望|w-v|的值最小,求最小值。
输入描述:
第一行输入一个正整数n, 表示战士数量(1<=n<=10^5)
第二行给出一个字符串s,仅由0或1组成,0表示这个战士只会进攻,1表示只会防守。
输出描述:
输出一行一个整数表示|w-v|的最小值。
示例1:

4
0011
输出:
1

示例2:

7
1000101
输出:
2

py代码:

if __name__ == '__main__':
	N = int(input())
	char = input()
	mid_num=10000000
	if N==1:
		print(0)
	else:
		for i in range(len(char)+1):
			w=0
			v=0
			pos = i #确定pos
			for j in range(len(char)):
				if j+1<=pos:
					if int(char[j])==0:
						w = w+j+1
				else:
					if int(char[j])==1:
						v = v+j+1
			if mid_num>=abs(w-v):
				mid_num = abs(w-v)
		print(mid_num)
def is_xunhuan(inputList):
	for i in range(len(inputList)):
		for j in range(len(inputList[i])):


第四题:
给出一个链表数组,该链表数组均是某一个环状链表的一部分,请你将这些链表数组合并成环状链表,然后需要找到一个位置,使得从这个位置将环切开后,按照顺序或者逆序遍历这个环,形成的链表字典序尽量小,并返回这条链。
1.链表字典序的定义:对于两个链表a,b,从头节点到尾节点遍历,找到第一个不相同的节点值,如果存在i使得a[i].val<b[i].val,那么我们认为,a的字典序是小于b的字典序的。
2.环状链表不存在相同的节点值。
3.该题环状链表节点个数最小为2。
4.每个链表都是在环状链表上的顺时针的一部分。
5.给定的链表数组一定能组成一个环状链表。
(本题是核心模式,不需要自己处理输入输出,完成函数即可)
示例1:

输入:
{{123}{234}{41}}
输出:
{1234}
说明:形成的环状链表为1=>2=>3=>4=>1=>2.....,从1断开,顺序遍历,得到最小字典序数列。

示例2:

输入:
[{3,7,4},{7,4,5,1,10,3}]
输出:
{1,5,4,7,3,10}

java代码:

import java.util.*;


class ListNode {
    int val;
    ListNode next = null;

    public ListNode(int val) {
        this.val = val;
    }
}

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * @param a ListNode类一维数组 指向每段碎片的开头
     * @return ListNode类
     */
    public ListNode solve(ListNode[] a) {
        // write code here
        HashMap<Integer, ListNode> nodeMap = new HashMap<>();
        HashMap<Integer, Integer> preMap = new HashMap<>();
        HashMap<Integer, Integer> nextMap = new HashMap<>();
        HashMap<Integer, Boolean> visitedMap = new HashMap<>();
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < a.length; i++) {
            printList(a[i]);
            for (ListNode p = a[i]; p != null; p = p.next) {
                nodeMap.put(p.val, p);
                if (p.next != null) {
                    preMap.put(p.next.val, p.val);
                    nextMap.put(p.val, p.next.val);
                }
                min = Math.min(min, p.val);
            }
        }
        ListNode head = new ListNode(0);
        head.next = null;
        ListNode rear = head;
        rear.next = nodeMap.get(min);
        rear = rear.next;
        rear.next = null;
        visitedMap.put(min, true);
        if (preMap.get(min) < nextMap.get(min)) {
            //前驱小 从前驱走
            while (!visitedMap.getOrDefault(preMap.get(min), false)) {
                min = preMap.get(min);
                rear.next = nodeMap.get(min);
                rear = rear.next;
                rear.next = null;
                visitedMap.put(min, true);
            }

        } else {
            //后继小 从后继走
            //前驱小 从前驱走
            while (!visitedMap.getOrDefault(nextMap.get(min), false)) {
                min = nextMap.get(min);
                rear.next = nodeMap.get(min);
                rear = rear.next;
                rear.next = null;
                visitedMap.put(min, true);
            }
        }
        printList(head);
        return head.next;
    }

    public void printList(ListNode head) {
        System.out.print("链表->{");
        for (ListNode p = head; p != null; p = p.next) {
            System.out.print(p.val+" ");
        }
        System.out.println("}");
    }
}

第五题:
现在有一个长度为n的价格数组a,表示某只股票每天的价格,你每天最多买入或者卖出该只股票的1手股票,买入或者卖出没有手续费,且卖出股票前必须手里已经有股票才能卖出,但是持有的股票数目不受限制,并且初始资金为m元,你在任意时刻都不能进行透支,所以你的资金必须始>=0,请问你在第n天结束之后,拥有最大的总资产是多少?(总资产:股票数目*股票价格+现金)
输入描述:
第一行两个正整数n,m{1<=n<=2000, 1<=m<=10^9}。
第二行n个正整数{an}{1<=ai<=10^9}
输出描述:
输出n天结束之后,拥有的最大总资产。
示例1:

输入:
6 2
2 3 1 1 1 2
输出:
6

示例2:

输入:
3 2
1 1 4
输出:
8

java代码:

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

public class Q5 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int prices[] = new int[n];
        for (int i = 0; i < n; i++) {
            prices[i] = sc.nextInt();
        }
        long dp[][] = new long[n][n];//dp[i][j] 表示在第i天拥有j注股票的最大资产 ,n天最多n-1支股票
        Arrays.fill(dp[0], -1);
        dp[0][0] = m;//00注股票拥有m元
        if (m >= prices[0]) {
            dp[0][1] = m - prices[0];
        }
        for (int i = 1; i < n; i++) {
            //两种情况
            //一是买入一注
            //一是卖出一注
            //一个是啥也不干
            for (int j = 0; j < n; j++) {
                //啥也不干
                dp[i][j] = dp[i - 1][j];
                //买入一注 并且金额足够
                if (j > 0) {
                    if (dp[i - 1][j - 1] != -1 && dp[i - 1][j - 1] >= prices[i]) {
                        dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - 1] - prices[i]);
                    }
                }
                //卖出一注
                if (j < n - 1) {
                    if (dp[i - 1][j + 1] != -1) {
                        dp[i][j] = Math.max(dp[i][j], dp[i - 1][j + 1] + prices[i]);
                    }
                }
            }
        }
        long ans = 0;
        for (int i = 0; i < n; i++) {
            if (dp[n - 1][i] == -1) continue;
            ans = Math.max(ans, dp[n - 1][i] + i * prices[n - 1]);
        }
       // print(dp);
        System.out.println(ans);
    }

    public static void print(int dp[][]) {
        int n = dp.length;
        System.out.print("\t\t");
        for (int i = 0; i < n; i++) {
            System.out.print("d" + i + "\t");
        }
        System.out.println();
        for (int i = 0; i < n; i++) {
            System.out.print(i + "注股票\t");
            for (int j = 0; j < n; j++) {
                System.out.print(dp[j][i] + "\t");
            }
            System.out.println();
        }
    }
}

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值