题目描述

这是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. Python Hacking Tools - Password Sniffing

    Password Sniffing with Scapy 1. Download and install the Scapy first. pip install scapy https://scap ...

  2. T133316 57级返校测试重测-T4-字符串的修改

    大致题意: 有一个A字符串和一个B字符串, 操作将A或A的一个后缀修改为B, 求最少的操作数. 有三个操作为: 删除: 删除掉 A 中的某一个字符. 添加: 将某一个字符添加到 A 中任意位置. 替换 ...

  3. oracle 启动报ORA-01105 ORA-19808

    bash-4.4$ srvctl start instance -i jfcddb2 -d jfcddb PRCR-1013 : Failed to start resource ora.jfcddb ...

  4. JAVA集合三:几种Set框架

    参考链接: HOW2J.CN HashSet简单讲解 HashSet HashSet与C++STL中Set基本类似,具有的特点便是: 集合中元素不可重复 集合中元素顺序 ≠ 插入顺序 常用方法 功能 ...

  5. React Native 报错 Error: spawn EACCES 权限

    权限不足,运行命令修改权限 chmod android/gradlew

  6. 面试题二十二:链表中倒数第k个节点

    方法一:双指针法定义两个指针A.B,A先走k-1步后再一起走,直到A.next==null注意: 1.链表为空 2.链表长度小于k 3.k<=0 当题目是求链表的中间节点时,可以两个指针从开头开 ...

  7. seaborn线性关系数据可视化:时间线图|热图|结构化图表可视化

    一.线性关系数据可视化lmplot( ) 表示对所统计的数据做散点图,并拟合一个一元线性回归关系. lmplot(x, y, data, hue=None, col=None, row=None, p ...

  8. PHPExcel将Excel数据导入数据库

    <?php //PHPExcel读取导入Excel数据到数据库(2003,2007通用)使用方法: //先用excel2array()方法将excel表中的数据存储到数组,在从遍历二维数组将数据 ...

  9. luogu P1128 [HNOI2001]求正整数 dp 高精度

    LINK:求正整数 比较难的高精度. 容易想到贪心不过这个贪心的策略大多都能找到反例. 考虑dp. f[i][j]表示前i个质数此时n的值为j的最小的答案. 利用高精度dp不太现实.就算上FFT也会T ...

  10. Use SQL to Query Data from CDS and Dynamics 365 CE

    from : https://powerobjects.com/2020/05/20/use-sql-to-query-data-from-cds-and-dynamics-365-ce/ Have ...