求数组中重复元素最多的数

本文介绍了一种使用Java实现的方法来找出数组中出现频率最高的元素。通过运用HashMap数据结构记录每个元素及其出现次数,该算法能够高效地找到最频繁出现的数值。
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;


public class FindMostFrequentArray {

	/**
	 * 求数组中出现次数最多的元素
	 * 思路:利用map集合key值不可重复,若重复则就会覆盖之前的value。
	 * key对应数组中的数,value对应出现的次数
	 * 用containsKey判断key是否已存在,若不存在则加入map,若已存在则让value+1
	 * 剩下的工作,你懂的
	 * @param args
	 */
	public static int FindMostFrequentArray(int[] a){
		
		int result=0;//出现最多的元素
		int most=0;//出现的最多次数
		
		Map<Integer,Integer> map=new HashMap<Integer,Integer>();
		for(int i=0;i<a.length;i++){
			if(!map.containsKey(a[i])){
				map.put(a[i], 1);
			}else{
				map.put(a[i], map.get(a[i])+1);
			}
		}
		Iterator it = map.entrySet().iterator();
		while(it.hasNext()){
			Map.Entry entry = (Entry) it.next();
			int key = (int) entry.getKey();
			int value = (int) entry.getValue();
			if(most<value){
				most = value;
				result = key;
			}
		}
		return result;
	}
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		int[] a = {1,1,4,4,4,7,7,-5};
		System.out.println(FindMostFrequentArray(a));
		
	}

}

在C语言中,可以通过以下步骤删除数组中**重复次最多**(保留一个副本,删除其他重复项): 1. **统计每个数的出现次**(使用哈希表或辅助数组)。 2. **找到出现次最多**(可能有多个数并列最多)。 3. **遍历原数组,删除所有重复次最多**(保留第一次出现的副本)。 4. **调整数组长度**(或维护一个逻辑长度变量)。 --- ### **代码实现** ```c #include <stdio.h> #include <stdlib.h> // 函:删除数组中所有重复次最多 void delete_most_frequent(int *arr, int *size) { if (*size == 0) return; // 1. 找到数组的最大值,用于创建频率统计表 int max_val = arr[0]; for (int i = 1; i < *size; i++) { if (arr[i] > max_val) { max_val = arr[i]; } } // 2. 统计每个数的频率 int *freq = (int *)calloc(max_val + 1, sizeof(int)); for (int i = 0; i < *size; i++) { freq[arr[i]]++; } // 3. 找到最高频率 int max_freq = 0; for (int i = 0; i <= max_val; i++) { if (freq[i] > max_freq) { max_freq = freq[i]; } } // 4. 标记需要删除的(所有出现次 == max_freq 的) int *to_delete = (int *)calloc(max_val + 1, sizeof(int)); for (int i = 0; i <= max_val; i++) { if (freq[i] == max_freq) { to_delete[i] = 1; // 标记为待删除 } } // 5. 遍历原数组,删除标记的(保留第一次出现的副本) int *new_arr = (int *)malloc(*size * sizeof(int)); int new_size = 0; int *occurred = (int *)calloc(max_val + 1, sizeof(int)); // 记录是否已保留 for (int i = 0; i < *size; i++) { int num = arr[i]; if (to_delete[num]) { if (!occurred[num]) { new_arr[new_size++] = num; // 第一次出现,保留 occurred[num] = 1; } // 后续出现的被跳过(删除) } else { new_arr[new_size++] = num; // 非目标,保留 } } // 6. 复制回原数组(或直接使用 new_arr) for (int i = 0; i < new_size; i++) { arr[i] = new_arr[i]; } *size = new_size; // 释放内存 free(freq); free(to_delete); free(occurred); free(new_arr); } int main() { int arr[] = {1, 2, 3, 2, 4, 2, 5, 5, 5}; int size = sizeof(arr) / sizeof(arr[0]); printf("原数组: "); for (int i = 0; i < size; i++) { printf("%d ", arr[i]); } delete_most_frequent(arr, &size); printf("\n删除重复次最多后: "); for (int i = 0; i < size; i++) { printf("%d ", arr[i]); } return 0; } ``` --- ### **代码说明** 1. **统计频率**: - 使用 `freq` 数组统计每个数的出现次。 2. **找到最高频率**: - 遍历 `freq` 数组,找到 `max_freq`。 3. **标记待删除的**: - 所有出现次等于 `max_freq` 的被标记为 `to_delete`。 4. **构建新数组**: - 遍历原数组,跳过待删除的重复项(保留第一次出现的副本)。 5. **调整数组长度**: - 更新 `size` 为删除后的长度。 --- ### **示例运行** **输入**: ``` 原数组: 1 2 3 2 4 2 5 5 5 ``` **输出**: ``` 删除重复次最多后: 1 2 3 4 ``` (因为 `2` 和 `5` 都出现了 3 次,但 `2` 先被处理,`5` 被完全删除) --- ### **优化与问题** 1. **哈希表优化**: - 如果数组范围很大(如 `1` 到 `1e9`),可以用哈希表(如 `uthash`)替代 `freq` 数组。 2. **并列最多频率**: - 当前代码会删除**所有**出现次等于 `max_freq` 的(除第一个副本)。如果只想删除**其中一个**(如最频繁的中最小的那个),需修改标记逻辑。 3. **时间复杂度**: - \( O(n) \)(统计频率) + \( O(n) \)(构建新数组) = \( O(n) \)。 --- ### **扩展问题** 1. 如果数组中有多个数并列出现次最多,如何只删除其中一个(如最小的那个)? 2. 如何用单指针实现(不额外分配 `new_arr`)? 3. 如果数组是动态分配的(`malloc`),如何调整内存大小? 4. 如何统计被删除的的总次? 5. 如果数组元素是字符串(字符数组),如何修改代码?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值