zoukankan      html  css  js  c++  java
  • 2016腾讯编程题:微信红包

    题目描述

    春节期间小明使用微信收到很多个红包,非常开心。在查看领取红包记录时发现,某个红包金额出现的次数超过了红包总数的一半。请帮小明找到该红包金额。写出具体算法思路和代码实现,要求算法尽可能高效。

    给定一个红包的金额数组gifts及它的大小n,请返回所求红包的金额。

    测试样例:
    [1,2,3,2,2],5
    返回:2

    解题

    题目要求一定存在大于数量一半的数,测试用例出现不到一半的情况。

    当一定存在大于一半的数时候,直接求中位数就好了,快排求中位数,在找到中位数,在统计中位数出现的次数,大于一半就是答案否则返回0 

    import java.util.*;
    
    public class Gift {
        public int getValue(int[] gifts, int n) {
            // write code here
            //if(n == 134)
           //     return 0;
            quickSort(gifts,0,n-1);
            int count = 0;
            for(int i = 0;i< n;i++){
                if(gifts[i] == gifts[n / 2])
                    count++;
            }
            return count>n/2?gifts[n/2]:0;
        }
        // 快速排序取中位数
        public void quickSort(int[] A,int low,int high){
            if(low >= high)
                return;
            int mid = partition(A,low,high);
            quickSort(A,low,mid - 1);
            quickSort(A,mid+1,high);
        }
        public int partition(int [] A,int low ,int high){
            int x = A[high];
            int i = low - 1;
            for( int j = low;j<= high - 1;j++){
                if( A[j] <= x){
                    i = i + 1;
                    int temp = A[i];
                    A[i] = A[j];
                    A[j] = temp;
                }
            }
            int temp = A[i+1];
            A[i+1] = A[high];
            A[high] = temp;
            return i + 1;
        }
    }

    参考剑指Offer

    在遍历数组的时候保存两个数:一个是数组中的一个数,一个是次数。当我们遍历到下一个数字的时候,如果下一个数和我们之前保存的数字相同,则次数加一;如果下一个数字和我们之前保存的数组不同,则次数减一。如果次数为0,我们需要更新保存的下一个数字,并把次数记作为1

    import java.util.*;
    
    public class Gift {
        public int getValue(int[] A, int n) {
            
            int count = 0;
            int mid = -1;
            for(int i = 0;i< n;i++){
                if(A[i] == mid){
                    count++;
                }else {
                    if(count!=0){
                        count--;
                    }else{
                        mid = A[i];
                        count = 1;
                    }
                }
            }
            count = 0;
            for(int i = 0;i< n;i++){
                if(A[i] == mid)
                    count++;
            }
            return count>n/2?mid:0;
        }
       
    }

    剑指offer上第一种方法不需要严格的排序,利用的快排的partition的思想,找到使得某一侧的划分在n/2附近这里就是中位数的位置。

    import java.util.*;
    
    public class Gift {
        public int getValue(int[] A, int n) {
            
            int count = 0;
            
            int midId = partition(A,0,n-1);
            while(midId != n/2){
                if(midId > n/2){
                    midId = partition(A,0,midId-1);
                }else{
                    midId = partition(A,midId+1,n-1);
                }
            }
            int mid = A[midId];
            for(int i = 0;i< n;i++){
                if(A[i] == mid)
                    count++;
            }
            return count>n/2?mid:0;
        }
        public int partition(int[] A,int low ,int high){
            int x = A[high];
            int i = low - 1;
            for(int j = low;j< high ;j++){
                if(A[j] <= x){
                    i = i + 1;
                    int tmp = A[i];
                    A[i] = A[j];
                    A[j] = tmp;
                }
            }
            int tmp = A[i + 1];
            A[i + 1] = A[high];
            A[high] = tmp;
            return i + 1;
        }
       
    }
  • 相关阅读:
    查看端口有没有被占用
    微信公众号2()
    How to insert a segment of noise to music file
    puppet practice
    Docker Commands
    LempelZiv algorithm realization
    The algorithm of entropy realization
    Java network programmingguessing game
    Deploy Openstack with RDO and Change VNC console to Spice
    puppet overview
  • 原文地址:https://www.cnblogs.com/theskulls/p/5387308.html
Copyright © 2011-2022 走看看