Java之基础算法(找出其中任意一个重复数字、去除链表重复元素、去除链表所有重复元素)

1、在长度为n的数组中,数组值为范围0-n-1范围内的整数,请找出其中任意一个重复的数字。
取值范围0-n-1
找出其中一个就可以
算法思想:从第一个开始,把数组值放在对应的下标值数组中,比如下标为0的值为5,那么就把5放在下标为0的数组中,这样如果有两个相同的数值就会放在同一个下标下,这样每一个元素最多移动两次就可以找到正确的位置。

   public static int duplicateNumber(int arr[]){
        if(arr==null||arr.length<1)
            return -1;
        for(int i=0;i<arr.length;i++){
            if(arr[i]<0||arr[i]>arr.length-1){
                return -1;
            }
        }
        for(int i=0;i<arr.length;i++){////只有在arr[i]!=i下是找到重复数字与原来同一个位置发生碰撞
            while(arr[i]!=i){//所有被交换到i位置的元素都放在了对应的位置 但并不是所有的元素都交换了 但下标为i的值一定是i,或者这一轮找到重复数字
                if(arr[i]==arr[arr[i]]){
                    return arr[i];
                }
                int temp=arr[i];
                arr[i]=arr[temp];
                arr[temp]=temp;
            }
        }
        return -1;
    }

上面这种情况可以找出其中一个(从最小下标开始找,应该是找到最小的第一个重复值)
2、与1同样的条件,找出所有重复的元素
空间换时间

 //花费一个与原数组大小相等的标记数字
 public static void findAllDuplicateBySpace(int arr[]){
     if(arr==null||arr.length<1){
         System.out.println(-1);
         return;
     }

     for(int i=0;i<arr.length;i++){
         if(arr[i]<0||arr[i]>=arr.length){
             System.out.println(-1); 
             return;
         }
     }
     int flag[]=new int[arr.length];
     for(int i=0;i<arr.length;i++){
         flag[arr[i]]++;
     }
     for(int i=0;i<flag.length;i++){
         if(flag[i]>1)
             System.out.print(i+" ");
     }
 } 

要节省空间就要花费时间排序

public static void quickSort(int arr[],int low,int high){
    int l=low;
    int h=high;
    int povit=arr[low];
    while(l<h){
        while(l<h&&arr[h]>=povit)
            h--;
        if(l<h){
            int temp=arr[h];//povit
            arr[h]=arr[l];
            arr[l]=temp;
            l++;
        }
        while(l<h&&arr[l]<=povit)
            l++;
        if(l<h){
            int temp=arr[l];//povit
            arr[l]=arr[h];
            arr[h]=temp;
            h--;
        }
    }
    if(l>low)quickSort(arr,low,l-1);
    if(h<high) quickSort(arr,l+1,high);   
 }
 //时间换空间 先排序
 public static void findAllDuplicateByTime(int arr[]){
     if(arr==null||arr.length<1){
         System.out.println(-1);
         return;
     }
     for(int i=0;i<arr.length;i++){
         if(arr[i]<0||arr[i]>=arr.length){
             System.out.println(-1);
             return; 
         }
     }
     quickSort(arr,0,arr.length-1); 
     System.out.println();
     for(int i=0;i<arr.length;i++){  
             System.out.print(arr[i]+" "); 
     }
     System.out.println();
     boolean isDuplicate=false;
     for(int i=0;i<arr.length-1;i++){
         if(arr[i]==arr[i+1]){
             if(!isDuplicate)
                 System.out.print(arr[i]+" "); 
             isDuplicate=true;
         }else{
             isDuplicate=false;
         }
     }
 }

3、去除链表中重复元素(重复元素留一个)

public class LinkTable {
    Node head=null;
    class Node{
        Node next;
        int value;
        public Node(int value){
            this.value=value;
        }
    }
    public void removeDuplicateNode(Node head){
        if(head==null)
            return;
        Node p=head;
        Node q=head;
        while(p.next!=null){
            if(p.value==p.next.value){
                 q=p.next;
                 p.next=p.next.next;
                 q.next=null;
            }else{
                p=p.next;
            }

        }
        p=head;
        while(p!=null){
            System.out.print(p.value+" ");
            p=p.next;
        }
    }

}

4、重复元素一个不留



    public void removeAllDuplicate(Node head){
        if(head==null)
            return;
        Node pPreNode=null;
        Node pNode=head;
        while(pNode!=null){
            Node pNext=pNode.next;
            boolean isDuplicate=false;
            if(pNext!=null&&pNext.value==pNode.value)
                isDuplicate=true;
            if(!isDuplicate){
                pPreNode=pNode;
                pNode=pNode.next;//保证和pNext重合与下面对应
            }else{
                int delValue=pNode.value;
                Node toDelNode=pNode;
                while(toDelNode!=null&&toDelNode.value==delValue){
                    pNext=toDelNode.next;
                    toDelNode.next=null;
                    //toDelNode=null;
                    toDelNode=pNext;    
                }
                //执行到这里 pNext都指向一个新的值节点(可能是重复的节点)pNode指向节点已经被删除了 所以下面需要连接 保证链是连接的
                if(pPreNode==null){//代表还没有找到第一个不重复的头节点
                    head=pNext;
                }else{
                    pPreNode.next=pNext;//pPreNode指向的还是没有重复的节点 要保证链表链不能断 上面会用到 pPreNode指向下一个pNode而不是自己后移 所以需要保证这个链不能断
                }
                pNode=pNext;///保证和pNext重合
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_26564827/article/details/80207741