一)有序数组去重
基本原理:
第一步:初始化两个指针,一个慢指针slow、一个快指针fast。
第二步:判断慢指针slow和快指针fast的值是否一致,如不一致,慢指针slow加1、并把快指针fast的值赋值给慢指针slow,然后快指针fast加1。
第三步:继续扫描后面的元素,如果慢指针slow和快指针fast的值一致,说明元素重复,快指针fast直接加1并继续扫描。
第四步:重复第二、第三步,当快指针fast走到末尾时,去重结束,返回第0位到慢指针slow位置的数据,,即是去重之后的数据。
有序数组去重图解:
有序数组去重源码:
/**
* 有序数组去重
* @param nums
* @return
*/
public static int[] arrayToWeigh(int[] nums) {
if (nums == null) {
return null;
}
int slow = 0; // 慢指针
int fast = 1; // 快指针
while (fast < nums.length) {
if (nums[slow] != nums[fast]) { // 如果慢指针的值和快指针的值不相等,表示元素不重复
slow++; // 慢指针加1
nums[slow] = nums[fast]; // 把快指针的值赋值给慢指针
}
fast++; // 快指针加1
}
// 把去重之后的数据重新复制成一个新数组返回
return Arrays.copyOfRange(nums, 0, slow + 1);
}
二)有序链表去重
基本原理:
同有序数组去重原理一样,唯一的区别是把数组赋值的操作变成了指针操作。
有序链表去重源码:
第一步:初始化链表结构和测试数据
public class LinkedListToWeigh<E> {
/** 初始化数据结构 */
static class Node<E> {
E data;
Node<E> next; // 指向下一结点
Node(E x) { data = x; }
}
private Node<E> head;
/** 从头部添加结点信息 */
public Node<E> add(E e) {
if (e == null) throw new NullPointerException();
Node<E> newNode = new Node<E>(e);
if (head == null) {
head = newNode;
} else {
newNode.next = head; // 把新结点的next指向头部节点
head = newNode; // 把新结点作为新的头部结点
}
return newNode;
}
public Node<Integer> init() {
// 添加链表结点
LinkedListToWeigh<Integer> linkedList = new LinkedListToWeigh<Integer>();
linkedList.add(1);
linkedList.add(1);
linkedList.add(3);
linkedList.add(3);
linkedList.add(3);
linkedList.add(4);
linkedList.add(4);
linkedList.add(4);
linkedList.add(4);
linkedList.add(7);
linkedList.add(7);
linkedList.add(7);
// 返回链表
return linkedList.head;
}
}
第二步:有序链表去重
/**
* 有序链表去重
* @param node
* @return
*/
public Node<E> linkedListToWeigh(Node<E> node) {
if (node == null) {
return null;
}
Node<E> slow = node; // 慢指针
Node<E> fast = node.next; // 快指针
while (fast != null) {
if (slow.data != fast.data) { // 判断慢指针和快指针的值是否相等
slow.next = fast; // 把快指针的值赋值给慢指针
slow = slow.next; // 慢指针前进1
}
fast = fast.next; // 快指针前进1
}
// 把链表断开,相当于把后面的元素抛弃了
slow.next = null;
return node;
}
第三步:main方法测试有序链表去重
public static void main(String[] args) {
LinkedListToWeigh<Integer> linkedList = new LinkedListToWeigh<Integer>();
// 源数据
Node<Integer> source = linkedList.init();
System.out.print("有序链表: ");
while (source != null) {
System.out.print(source.data + " ");
source = source.next;
}
// 有序链表去重之后的数据
Node<Integer> node = linkedList.linkedListToWeigh(linkedList.init());
System.out.print("\n有序链表数据去重: ");
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
}
打印效果图:
三)字符串去重,并统计字符个数
基本原理:利用HashMap中key不会重复的特性。
第一步:将字符串拆分,每一个字符作为Map中的key
第二步:判断key是否在Map中存在,当Map中存在key时,value累计加1,当Map中不存在key时, value默认为1。
备注:如不需要统计字符个数,还可用HashSet中的add方法去重。
字符串去重源码:
/**
* 字符串去重,并统计字符个数
* 备注: 利用HashMap中key不会重复的特性
* @param s
* @return
*/
public static Map<Character, Integer> stringToWeigh(String s) {
if (s == null || s.length() == 0) {
return null;
}
Map<Character, Integer> map = new HashMap<Character, Integer>();
for (int i = 0; i < s.length(); i++) {
if (map.containsKey(s.charAt(i))) {
map.put(s.charAt(i), map.get(s.charAt(i))+1); // 当Map中存在key时, value累计加1
} else {
map.put(s.charAt(i), 1); // 当Map中不存在key时, value默认为1
}
}
return map;
}
// main测试代码
public static void main(String[] args) {
String s = "aa11444bca44ccd";
System.out.println(stringToWeigh(s));
// 输出:{a=3, 1=2, b=1, c=3, 4=5, d=1}
}
识别二维码关注个人微信公众号
本章完结,待续,欢迎转载!
本文说明:该文章属于原创,如需转载,请标明文章转载来源!