题目描述

这是2021广联达校招提前批笔试算法题之一。

我们希望一个序列中的元素是各不相同的,但是理想和显示往往是有差距的。现在给出一个序列A,其中难免有相同的元素,现在提供了一种变化方式,使得经过若干次操作后一定可以得到一个元素各不相同的序列。

这个操作是这样的,令x为序列中最小的重复数字,你需要删除序列左数第一个x,并把第二个x替换为2*x。请你输出最终的序列。

例如原序列是[2,2,1,1,1],一次变换后变为[2,2,2,1],两次变换后变为[4,2,1],变换结束。

输入描述

输入第一行包含一个正整数n,表示序列的长度为n。(1<=n<=50000)

第二行有n个整数,初始序列中的元素。(1<=a_i<=10^8)

输出描述

输出包含若干个整数,即最终变换之后的结果。

算法思路

通过HashSet和HashMap实现重复元素存入集合以及元素出现次数的统计;

递归思想。

算法实现

import java.util.*;

/**
* @author Chiaki
*/
public class Main {
public static void main(String[] args) {
int n = 6;
int[] arr = {1,1,2,2,4,4};
long s = System.currentTimeMillis();
int[] res = getArray(n, arr);
long e = System.currentTimeMillis();
System.out.println("耗时:" + (e - s) + "ms");
System.out.print("[");
for (int i = 0; i < res.length; i++) {
if (i < res.length - 1) {
System.out.print(res[i] + ",");
} else {
System.out.print(res[i] + "]");
}
}
System.out.println();
} /**
* 按规则处理数组并返回新的无重复元素的数组
* @param n 数组长度
* @param arr 初始数组
* @return 无重复元素的数组
*/
public static int[] getArray(int n, int[] arr) {
// 递归停止条件:只有一个元素直接返回无需进行后续操作
if (n == 1) {
return arr;
}
List<Integer> list = new LinkedList<>();
Set<Integer> set = new HashSet<>();
Map<Integer,Integer> map = new HashMap<>(n);
// 遍历数组
for (int i : arr) {
// 数组值放入链表方便操作
list.add(i);
// 利用HashSet判断元素重复
// 并统计元素出现次数放入HashMap
if (!set.add(i)) {
int count = map.get(i);
count++;
map.put(i, count);
continue;
}
map.put(i, 1);
}
// 递归停止条件:HashSet元素个数与数组长度相同
if (set.size() == n) {
return arr;
}
// 将HashSet清空用来存放重复的元素
set.clear();
for (Integer i : map.keySet()) {
if (map.get(i) > 1) {
set.add(i);
}
}
// 按规则去重 迭代停止条件:HashSet为空
while (!set.isEmpty()) {
// 从最小的重复元素开始
int minValue = Collections.min(set);
// 定义计数器
int count = 1;
// 遍历链表
for (int i = 0; i < list.size(); i++) {
// 碰到重复元素的第一个时赋值为0 计数器自增
if (list.get(i).equals(minValue) && count == 1) {
list.set(i, 0);
count++;
}
// 碰到重复元素的第二个时按要求赋值 计数器自增
if (list.get(i).equals(minValue) && count == 2) {
list.set(i, 2 * list.get(i));
count++;
}
}
// 操作结束后移除HashSet的当前重复元素并继续迭代
set.remove(minValue);
}
// 将链表中赋值为0的元素删除
list.removeIf(s -> s.equals(0));
// 剩下的元素存放到数组作为结果
int[] res = new int[list.size()];
for (int i = 0; i < res.length; i++) {
res[i] = list.get(i);
}
// 另外一种简单写法
/*int[] res = list.stream().mapToInt(Integer::valueOf).toArray();*/
// 递归调用
return getArray(res.length, res);
}
}

运行结果

耗时:33ms

[2,8,4]

提前批笔试一道算法题的Java实现的更多相关文章

  1. 常见排序算法题(java版)

    常见排序算法题(java版) //插入排序:   package org.rut.util.algorithm.support;   import org.rut.util.algorithm.Sor ...

  2. 每天一道算法题(4)——O(1)时间内删除链表节点

    1.思路 假设链表......---A--B--C--D....,要删除B.一般的做法是遍历链表并记录前驱节点,修改指针,时间为O(n).删除节点的实质为更改后驱指针指向.这里,复制C的内容至B(此时 ...

  3. [2]十道算法题【Java实现】

    前言 清明不小心就拖了两天没更了-- 这是十道算法题的第二篇了-上一篇回顾:十道简单算法题 最近在回顾以前使用C写过的数据结构和算法的东西,发现自己的算法和数据结构是真的薄弱,现在用Java改写一下, ...

  4. 从一道算法题实现一个文本diff小工具

    众所周知,很多社区都是有内容审核机制的,除了第一次发布,后续的修改也需要审核,最粗暴的方式当然是从头再看一遍,但是编辑肯定想弄死你,显然这样效率比较低,比如就改了一个错别字,再看几遍可能也看不出来,所 ...

  5. 【每天一道算法题】时间复杂度为O(n)的排序

    有1,2,……一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度为O(1),使用交换,而且一次只能交换两个数. 这个是以前看到的算法题,题目不难.但是要求比较多,排序算法中,时间 ...

  6. 大公司面试经典数据结构与算法题C#/Java解答

    几个大公司(IBM.MicroSoft and so on)面试经典数据结构与算法题C#解答 1.链表反转 我想到了两种比较简单的方法 第一种是需要开一个新的链表,将原链表的元素从后到前的插入到新链表 ...

  7. 每天一道算法题-leetcode136-只出现一次的数字

    前言 打卡第一天 2019.10.26日打卡 算法,即解决问题的方法.同一个问题,使用不同的算法,虽然得到的结果相同,但是耗费的时间和资源是不同的.这就需要我们学习算法,找出哪个算法更好. 大家都知道 ...

  8. 一道算法题加深我对C++中map函数的理解

    一.一道题目引发我对map函数的考量 首先是题目大意:有n个银行,a[i]表示这个人在第i个银行有a[i]块钱(可以是负数),所有银行的钱加起来正好是0.每次只能在相邻的银行之间转账,问最少要转多少次 ...

  9. 【每天一道算法题】Numeric Keypad

    题目描述 The numberic keypad on your mobile phone looks like below: 123 456 789  0  suppose you are hold ...

随机推荐

  1. 索引中丢失 IN 或 OUT 参数:: 103,解决办法

    索引中丢失  IN 或 OUT 参数:: 103 这个原因是数据库中的字段类型与SQL语句中的类型不匹配造成的,103代表第103个字段参数错误.找到对应参数配置或者SQL中这个参数的类型是否与数据库 ...

  2. Go Pentester - HTTP CLIENTS(1)

    Building HTTP Clients that interact with a variety of security tools and resources. Basic Preparatio ...

  3. 集训作业 洛谷P1433 吃奶酪

    嗯?这题竟然是个绿题. 这个题真的不难,不要被他的难度吓到,我们只是不会计算2点之间的距离,他还给出了公式,这个就有点…… 我们直接套公式去求出需要的值,然后普通的搜索就可以了. 这个题我用的深搜,因 ...

  4. 尝鲜刚发布的 SpringFox 3.0.0,以前造的轮子可以不用了...

    最近 SpringFox 3.0.0 发布了,距离上一次大版本2.9.2足足有2年多时间了.可能看到这个名字,很多读者会有点陌生.但是,只要给大家看一下这两个依赖,你就知道了! <depende ...

  5. vuex : 模块化改造

    我们知道,vuex是vue技术栈中很重要的一部分,是一个很好用的状态管理库. 如果你的项目没有那么复杂,或者对vuex的使用没有那么重度,那么,是用不着modules功能的. 但如果你写着写着就发现你 ...

  6. Python面试题!百度大牛总结十条Python面试题陷阱

    无论是应聘Python web开发,爬虫工程师,或是数据分析,还是自动化运维,都涉及到一些基础的知识!我挑了一些Python的基础面试题,看看你能不能的答上来,也许面试的同学用的着! 问题1:请问如何 ...

  7. 写verilog程序需要注意的地方

    1.在always块语句中一定要注意if-else if-else if-else的判断条件的顺序. 2.同一个寄存器信号只能在同一个always or initial 块中进行赋值. 3.在控制一个 ...

  8. epic游戏平台如何启用认证器应用程序/二次验证码/谷歌身份验证器?

    1.登陆epic游戏平台,找到二次验证绑定界面 登陆https://www.epicgames.com/store/zh-CN/, 点右上角用户头像-[账户]. 之后点-[密码与安全] 在[双重验证] ...

  9. 初学Vue.js,用 vue ui 创建项目会不会被鄙视

    全栈的自我修养: 6使用vue ui进行vue.js环境搭建 It is only with the heart that one can see rightly. What is essential ...

  10. AList的具体实现 #CS61B-sp18-2.5

    实现一个Array based list,其功能包括获取长度size,添加元素至最后addLast,得到元素get和去除最后一个元素. 设计思路及其实现: 我们都知道在获取数据的时候,直接调用缓存里面 ...