[算法]和最大的连续降序字符

和最大的连续降序字符

题目地址

题目描述

Description

Archana is very fond of strings. She likes to solve many questions related to strings. She comes across a problem which she is unable to solve. Help her to solve. The problem is as follows: Given is a string of length L. Her task is to find the longest string from the given string with characters arranged in descending order of their ASCII code and in arithmetic progression. She wants the common difference should be as low as possible(at least 1) and the characters of the string to be of higher ASCII value.

Input

The first line of input contains an integer T denoting the number of test cases. Each test contains a string s of lengthL.

1<= T <= 100

3<= L <=1000

A<=s[i]<=Z

The string contains minimum three different characters.

Output

For each test case print the longest string.Case 1:Two strings of maximum length are possible- “CBA” and “RPQ”. But he wants the string to be of higher ASCII value therefore, the output is “RPQ”.Case 2:The String of maximum length is “JGDA”.

Sample Input 1

2
ABCPQR
ADGJPRT

Sample Output 1

RQP
JGDA
思路解析
  1. 在给定的字符串中在任意位置选取任意个数的字符,这些字符必须满足它们之间的差相同,比如ABC,ACE, ACEG, BDFH
  2. 将满足1的字符串中选取最长的某些字符串,比如 ACEG … BDFH等等
  3. 在满足2的字符串中选取其ASC码最大的字符串比如BDFH
  4. 将满足3的字符串逆序输出
代码实现
python

时间复杂度: O(n3)

步骤:

  1. 因为可以从任意位置选取任意多的字符,所以首先将给定字符串转成减掉A后的ASC码,这样A对应0,B对应1…,Z对应25,并进行去重和排序
  2. 创建数组,将给定的字符位置标记为1,没有的标记为0
  3. 遍历数组,对标记为1的数,分别进行距离为1,2…k的探测,记录满足条件的数
  4. 输出最佳答案

这样每次遍历的都是以第i个数开头的,以距离为1,2…k的串

if __name__ == '__main__':
    for _ in range(int(input())):
        # init
        s = input()
        s_arr = sorted(list(set(map(lambda x: ord(x) - ord("A"), s))))
        arr = [0] * 26
        for x in s_arr:
            arr[x] = 1
        # core
        # print(arr)
        best_count = 0
        best_res = " "
        for i in range(len(arr)):# 遍历数组,首先选定第i个数
            if arr[i] == 1:# 若当前数存在
                k = 1 # 步长从1开始
                while i + k < len(arr): # 指定步长为1,2,...k
                    count = 0
                    res = ""
                    for j in range(i, len(arr), k):  # 按照步长去遍历每个数
                        if arr[j] == 1: # 若该数存在
                            count += 1  
                            res = chr(j + ord("A")) + res
                        else: # 该数不存在则停止
                            break 
                    if count > best_count:
                        best_res = res
                        best_count = count
                    elif count == best_count:
                        if res[0] > best_res[0]:
                            best_res = res
                    k += 1
        print(best_res)

java

import java.io.*;
import java.util.*;
class Main {
	public static void main (String[] args) {
    	Scanner sc = new Scanner(System.in);
    	int t = sc.nextInt();
    	while(t-->0) {
        	char[] s = sc.next().toCharArray();
        	boolean[] ch = new boolean[26];
        	for(int i = 0; i<s.length; i++)
            	ch[s[i]-'A'] = true;
            String res = "";
            for(int i = 1; i<26; i++) {
                for(int j = 25; j>=0; j--) {
                    if(ch[j]) {
                        String temp = "";
                        temp+=(char)('A'+j);
                        for(int k = j-i; k>=0; k-=i) {
                            if(ch[k])
                                temp+=(char)('A'+k);
                            else
                                break;
                        }
                        if(temp.length()>res.length())  # 大于其实也是有问题,建议看上面python
                            res = temp;
                    }
                }
            }
            System.out.println(res);
    	}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值