码迷,mamicode.com
首页 > 编程语言 > 详细

算法练习

时间:2018-04-14 13:55:37      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:contains   算法   thml   操作   int()   sys   就是   scanner   序列   

1、输入一串数 等于某值的数的个数——hashmap的使用

我的做法,先读入这一串数,遍历一遍找出等于某个值的数的个数,超时(空间复杂度低但时间复杂度高)

正确做法,在读入这一串数的同时创建一个hanshmap key为值、value为个数,直接找出等于某个值的数的个数

import java.util.*;
public class Main{
    public static void main(String[]args){
        Scanner in=new Scanner(System.in);
        while(in.hasNext()) {
            LinkedHashMap<Integer,ArrayList<Integer>>map=new LinkedHashMap<>();
            int n=in.nextInt();
            int[]a=new int[n];
            for(int i=0;i<n;i++) {
                a[i]=in.nextInt();
                if(map.containsKey(a[i])) {
                    map.get(a[i]).add(i+1);
                }else {
                    ArrayList<Integer>list=new ArrayList<Integer>();
                    list.add(i+1);
                    map.put(a[i], list);
                }
            }
            int q=in.nextInt();
            for(int i=0;i<q;i++) {
                int l=in.nextInt();
                int r=in.nextInt();
                int k=in.nextInt();
                int count=0;
                ArrayList<Integer>list=map.get(k);
                if(list!=null&&list.size()!=0) {
                    for(Integer num:list) {
                        if(num>=l&&num<=r)
                            count++;
                    }
                }
                System.out.println(count);
            }
        }
    }
}

2、字符串S由小写字母构成,长度为n。定义一种操作,每次都可以挑选字符串中任意的两个相邻字母进行交换。询问在至多交换m次之后,字符串中最多有多少个连续的位置上的字母相同?——区间动态规划

 

要求移动后形成的最长连续子串,这个最长连续子串可能全是ab……c。因此,这里需要枚举移动后形成的最长连续子串里面所包含的字母;

确定了里面包含的字母,就可以专注于这个字母了,也就是说其余的字母都是没有用的,把它们从序列中挖掉;然后就值剩下目标字母了,目标字母离散地分布在序列中,因此,再离散化一下,搞完之后会生成一个行的序列,之后的动态规划就在新的序列上进行。

下面的图片表达了上述过程:

技术分享图片

现在新的序列pos看起来是合在了一起,形成了最长连续子序列,但是,形成这些连续序列所需要的操作次数是多少呢?如果操作次数大于m,那么该序列就是不满足要求的;

因此,这里面就可以得出区间动态规划了,先从小到大枚举段长,依次求得该段长的所有子序列的操作次数,并判断是否小于等于m,如果满足要求,就更新答案。

从小到大枚举段长是为了利用子问题的结果;dp[i][j]表示把pos[i]pos[j]之间的目标字母移动到一起,形成j - i + 1长度的连续子序列所需要的操作次数;

状态转移方程:dp[i][i + len - 1] = dp[i + 1][i + len - 2] + pos[i + len - 1] - pos[i] - len + 1;,依据是|x?a|+|x?b||x?a|+|x?b|在什么时候取得最小值。用最小的移动次数把两个目标字母移动到一起的方法就是把两个目标字母都往中间靠,状态转移方程就是根据这个来的,先把pos[i + 1] ~ pos[i + len - 2]之间的目标字母移动到一起,这个移动次数就是dp[i + 1][i + len - 2],然后把两个端点pos[i]pos[i + len -1]处的目标字母往中间靠,所需要的移动次数是pos[i + len - 1] - pos[i] - len + 1

算法练习

标签:contains   算法   thml   操作   int()   sys   就是   scanner   序列   

原文地址:https://www.cnblogs.com/zealousness/p/8831159.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!