zoukankan      html  css  js  c++  java
  • 面试题—小算法30题

    1、和为S的连续正数序列

    Java实现:

    package com.mian.algorithm;
    
    import java.util.ArrayList;
    
    public class FindContinuousSequence {
        public static void main(String[] args) {
            FindContinuousSequence continuousSequence=new FindContinuousSequence();
            ArrayList<ArrayList<Integer>> list=continuousSequence.findContinuousSequence(100);
            for(int i=0;i<list.size();++i){
                for(int j=0;j<list.get(i).size();++j){
                    System.out.print(list.get(i).get(j)+" ");
                }
                System.out.println();
            }
        }
        private ArrayList<ArrayList<Integer>> findContinuousSequence(int sum){
            ArrayList<ArrayList<Integer>> res=new ArrayList<ArrayList<Integer>>();
            if(sum<=1){
                return res;
            }
            int start=1;
            int end=2;
            while(start!=(1+sum)/2){
                int curSum=(start+end)*(end-start+1)/2;
                if(curSum==sum){
                    ArrayList<Integer> list=new ArrayList<Integer>();
                    for(int i=start;i<=end;++i){
                        list.add(i);
                    }
                    res.add(list);
                    ++start;
                    ++end;
                }else if(curSum<sum){
                    ++end;
                }else{
                    ++start;
                }
            }
            return res;
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 #include<vector>
     3 
     4 using namespace std;
     5 
     6 vector<vector<int>> findContinuousSequence(int sum)
     7 {
     8     vector<vector<int>> res;
     9     if (sum <= 1)
    10         return res;
    11     int start = 1;
    12     int end = 2;
    13     while (start != (1 + sum) / 2)
    14     {
    15         int curSum = (start + end)*(end - start + 1) / 2;
    16         if (curSum == sum)
    17         {
    18             vector<int> tmp;
    19             for (int i = start; i <= end; ++i)
    20                 tmp.push_back(i);
    21             res.push_back(tmp);
    22             tmp.clear();
    23             ++start;
    24             ++end;
    25         }
    26         else if (curSum < sum)
    27             ++end;
    28         else
    29             ++start;
    30     }
    31     return res;
    32 }
    33 
    34 int main()
    35 {
    36     vector<vector<int>> res = findContinuousSequence(100);
    37     for (int i = 0; i < res.size(); ++i)
    38     {
    39         for (int j = 0; j < res[i].size(); ++j)
    40             cout << res[i][j] << " ";
    41         cout << endl;
    42     }
    43 
    44     return 0;
    45 }
    View Code

    2、如何判断一个链表是否有环,如果有环,则返回第一个进入环的节点,没有则返回null。
    第一步,找环中相汇点。分别用p1,p2指向链表头部,p1每次走一步,p2每次走二步,直到p1==p2找到在环中的相汇点。
    第二步,找环的入口。接上步,当p1==p2时,p2所经过节点数为2x,p1所经过节点数为x,设环中有n个节点,p2比p1多走一圈,有2x=n+x;n=x; 可以看出p1实际走了一个环的步数,再让p2指向链表头部,p1位置不变,p1,p2每次走一步直到p1==p2; 此时p1指向环的入口。

    Java实现:

    package com.mian.algorithm;
    
    import java.util.Scanner;
    
    class ListNode{
        int val;
        ListNode next;
        ListNode(){}
        ListNode(int x){
            this.val=x;
            this.next=null;
        }
    }
    
    public class GetLoopNode {
        public static void main(String[] args){
            GetLoopNode getLoopNode=new GetLoopNode();
            ListNode head=getLoopNode.createList();
            getLoopNode.printList(head);
            ListNode p=head.next.next;
            ListNode last=head;
            while(last.next!=null){
                last=last.next;
            }
            last.next=p;
            ListNode node=getLoopNode.getLoopNode(head);
            System.out.println(node.val);
        }
        private ListNode getLoopNode(ListNode head){
            if(head==null||head.next==null||head.next.next==null){
                return null;
            }
            ListNode slow=head;
            ListNode fast=head;
            while(fast!=null&&fast.next!=null){
                slow=slow.next;
                fast=fast.next.next;
                if(slow==fast){
                    fast=head;
                    while(slow!=fast){
                        slow=slow.next;
                        fast=fast.next;
                    }
                    return slow;
                }
            }
            return null;
        }
        private void printList(ListNode head){
            if(head==null){
                return;
            }
            ListNode p=head;
            while(p.next!=null){
                System.out.print(p.val+" ");
                p=p.next;
            }
            System.out.println(p.val);
        }
        private ListNode createList(){
            int val;
            ListNode head=null;
            System.out.println("enter list value (enter 100 to quit):");
            Scanner sc=new Scanner(System.in);
            val=sc.nextInt();
            if(val==100){
                return head;
            }else{
                head=new ListNode(val);
                head.next=createList();
            }
            return head;
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 
     3 using namespace std;
     4 
     5 class ListNode
     6 {
     7 public:
     8     int val;
     9     ListNode* next;
    10     ListNode() {}
    11     ListNode(int x) :val(x), next(nullptr) {}
    12 };
    13 
    14 ListNode* createNode()
    15 {
    16     int in;
    17     ListNode* head = nullptr;
    18     cout << "enter list value (enter 100 to quit):";
    19     cin >> in;
    20     if (in == 100)
    21         return head;
    22     else
    23     {
    24         head = new ListNode(in);
    25         head->next = createNode();
    26     }
    27     return head;
    28 }
    29 
    30 void printList(ListNode* head)
    31 {
    32     if (head == nullptr)
    33         return;
    34     ListNode* p = head;
    35     while (p)
    36     {
    37         cout << p->val << " ";
    38         p = p->next;
    39     }
    40     cout << endl;
    41 }
    42 
    43 ListNode* getLoopNode(ListNode* head)
    44 {
    45     if (!head || !head->next || !head->next->next)
    46         return head;
    47     ListNode* n1 = head->next;
    48     ListNode* n2 = head->next->next;
    49     while (n1 != n2)
    50     {
    51         if (!n1->next || !n2->next->next)
    52             return nullptr;
    53         n1 = n1->next;
    54         n2 = n2->next->next;
    55     }
    56     n2 = head;
    57     while (n1 != n2)
    58     {
    59         n1 = n1->next;
    60         n2 = n2->next;
    61     }
    62     return n1;
    63 }
    64 
    65 int main()
    66 {
    67     ListNode* head = createNode();
    68     printList(head);
    69     ListNode* p = head->next->next;
    70     ListNode* last = head;
    71     while (last->next)
    72         last = last->next;
    73     last->next = p;
    74     cout << getLoopNode(head)->val << endl;
    75 
    76     return 0;
    77 }
    View Code

    3、回文字符串

    Java实现:

    package com.mian.algorithm;
    
    public class IsPalindrome {
        public static void main(String[] args) {
            String str="abceda";
            String str2="";
            String str3="abdba";
            boolean flag=isPalindrome(str3);
            System.out.println(flag);
        }
        private static boolean isPalindrome(String str){
            int size=str.length();
            if(size==0||str.isEmpty()){
                return false;
            }
            int i=0;
            while(i<size/2){
                if(str.charAt(i)!=str.charAt(size-i-1)){
                    return false;
                }
                ++i;
            }
            return true;
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 #include<string>
     3 
     4 using namespace std;
     5 
     6 bool isPalindrome(string &str)
     7 {
     8     int size = str.size();
     9     if (size == 0 || str.empty())
    10         return false;
    11     int i = 0;
    12     while (i < size / 2)
    13     {
    14         if (str[i] != str[size - i - 1])
    15             return false;
    16         ++i;
    17     }
    18     return true;
    19 }
    20 
    21 int main()
    22 {
    23     string str = "abceba";
    24     cout << isPalindrome(str) << endl;
    25 
    26     return 0;
    27 }
    View Code

    4、不使用循环,判断一个数是否是2的N次方
    凡是2的N次方的整数,其二进制码只有一个1

    Java实现:

    package com.mian.algorithm;
    
    public class Is2N {
        public static void main(String[] args) {
            boolean flag=is2N(16);
            System.out.println(flag);
        }
        private static boolean is2N(int n){
            if((n>0)&&((n&(n-1))==0)){
                return true;
            }
            return false;
        }
    }
    View Code

    C++实现:

    1 bool is2N(int n)
    2 {
    3     if ((n > 0) && ((n&(n - 1)) == 0))
    4         return true;
    5     return false;
    6 }
    View Code

    5、求1!+2!+3!+4!+...+n!的结果。

    Java实现:

    package com.mian.algorithm;
    
    public class JieChengHe {
        public static void main(String[] args){
            int res=jieChengHe(4);
            System.out.println(res);
            System.out.println(jieChengHeNoRec(4));
        }
        private static long jieChengHeNoRec(int n){
            long sum=0,num=1;
            for(int i=1;i<=n;++i){
                num*=i;
                sum+=num;
            }
            return sum;
        }
        private static int jieChengHe(int n){
            if(n==1){
                return 1;
            }
            return jieChengHe(n-1)+jieCheng(n);
        }
        private static int jieCheng(int n){
            if(n==1){
                return 1;
            }
            return jieCheng(n-1)*n;
        }
    }
    View Code

    C++实现:

     1 int jieCheng(int n)
     2 {
     3     if (n == 1)
     4         return 1;
     5     return n*jieCheng(n - 1);
     6 }
     7 
     8 int jieChengHe(int n)
     9 {
    10     if (n == 1)
    11         return 1;
    12     return jieChengHe(n - 1) + jieCheng(n);
    13 }
    View Code

    6、N的阶乘末尾有多少个0
    分析:N的阶乘可以分解为: 2的X次方,3的Y次方,4的K次方,5次Z方,.....的乘积。由于10 = 2 * 5,所以M只能和X和Z有关,每一对2和5相乘就可以得到一个10,于是M = MIN(X,Z),不难看出X大于Z,因为被2整除的频率比被5整除的频率高的多。所以可以把公式简化为M=Z。

    Java实现:

    package com.mian.algorithm;
    
    public class JieChengLastZero {
        public static void main(String[] args) {
            int res=jieChengLastZero(10);
            System.out.println(res);
        }
        private static int jieChengLastZero(int n){
            if(n<0){
                return 0;
            }
            int res=0;
            for(int i=5;i<=n;++i){
                int j=i;
                while(j%5==0){
                    ++res;
                    j=j/5;
                }
            }
            return res;
        }
    }
    View Code

    C++实现:

     1 int  jieChengLastZero(int n)
     2 {
     3     if (n < 0)
     4         return;
     5     int res = 0;
     6     for (int i = 5; i <= n; ++i)
     7     {
     8         int j = i;
     9         while (j % 5 == 0)
    10         {
    11             ++res;
    12             j = j / 5;
    13         }
    14     }
    15     return res;
    16 }
    View Code

    7、在字符串中求最长数字子序列的长度

    Java实现:

    package com.mian.algorithm;
    
    public class LongestNumSubString {
        public static void main(String[] args){
            String str="ad3299adfa3239028903afd";
            System.out.println(longestNumSubString(str));
        }
        private static int longestNumSubString(String str){
            int size=str.length();
            if(size==0||str.isEmpty()){
                return 0;
            }
            int cnt=0;
            int num=0;
            for(int i=0;i<size;++i){
                if(isNumber(str.charAt(i))){
                    ++cnt;
                    if(cnt>num){
                        num=cnt;
                    }
                }else{
                    cnt=0;
                }
            }
            return num;
        }
        private static boolean isNumber(char c){
            int n=c-48;
            if(n>=0&&n<=9){
                return true;
            }
            return false;
        }
    }
    View Code

    C++实现:

     1 bool isNumber(char c)
     2 {
     3     int d = c - 48;
     4     if (d >= 0 && d <= 9)
     5         return true;
     6     return false;
     7 }
     8 
     9 int longestNumSubString(string &str)
    10 {
    11     int size = str.size();
    12     if (str.empty() || size == 0)
    13         return 0;
    14     int max = 0;
    15     int cnt = 0;
    16     for (int i = 0; i < size; ++i)
    17     {
    18         if (isNumber(str[i]))
    19         {
    20             cnt++;
    21             if (cnt > max)
    22                 max = cnt;
    23         }
    24         else
    25             cnt = 0;
    26     }
    27     return max;
    28 }
    View Code

     8、最长递增子序列

    Java实现:

    package com.mian.algorithm;
    
    public class LongestSequence {
        public static void main(String[] args) {
            int[] arr={ 4,1,2,5,0,3,6,8 };
            int[] res=longestSequence(arr);
            for(int i=0;i<res.length;++i){
                System.out.print(res[i]+" ");
            }
        }
        private static int[] longestSequence(int[] arr){
            int size=arr.length;
            if(size==0||arr==null){
                return null;
            }
            // 记录当前各元素作为最大元素的最长递增序列长度
            int[] maxLen=new int[size];
            // 记录当前以该元素作为最大元素的递增序列中该元素的前驱节点,用于打印序列用
            int[] pre=new int[size];
            for(int i=0;i<size;++i){
                maxLen[i]=1;
                pre[i]=i;
            }
            int k=0;
            int m=1;
            for(int i=0;i<size;++i){
                for(int j=0;j<i;++j){
                    if(arr[j]<arr[i]&&maxLen[j]+1>maxLen[i]){
                        maxLen[i]=maxLen[j]+1;
                        pre[i]=j;
                    }
                    if(m<maxLen[i]){
                        m=maxLen[i];
                        k=i;
                    }
                }
            }
            int i=m-1;
            int[] res=new int[m];
            while(pre[k]!=k){
                res[i--]=arr[k];
                k=pre[k];
            }
            res[i]=arr[k];
            return res;
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 #include<vector>
     3 
     4 using namespace std;
     5 
     6 vector<int> longestSequence(vector<int> &arr)
     7 {
     8     int size = arr.size();
     9     if (arr.empty() || size == 0)
    10         return vector<int>();
    11     // 记录当前各元素作为最大元素的最长递增序列长度
    12     vector<int> maxLen(size);
    13     // 记录当前以该元素作为最大元素的递增序列中该元素的前驱节点,用于打印序列用
    14     vector<int> pre(size);
    15     for (int i = 0; i < size; ++i)
    16     {
    17         maxLen[i] = 1;
    18         pre[i] = i;
    19     }
    20     int k = 0;
    21     int max = 1;
    22     for (int i = 1; i < size; ++i)
    23     {
    24         // 找到以array[i]为最末元素的最长递增子序列
    25         for (int j = 0; j < i; ++j)
    26         {
    27             //如果求非递减子序列只需将array[j] < array[i]改成<=,如果要求递减子序列只需改为>
    28             if (arr[j]<arr[i] && maxLen[j] + 1>maxLen[i])
    29             {
    30                 maxLen[i] = maxLen[j] + 1;
    31                 pre[i] = j;
    32             }
    33             if (max < maxLen[i])
    34             {
    35                 max = maxLen[i];
    36                 k = i;
    37             }
    38         }
    39     }
    40     int i = max - 1;
    41     vector<int> res(max);
    42     while (pre[k] != k)
    43     {
    44         res[i--] = arr[k];
    45         k = pre[k];
    46     }
    47     res[i] = arr[k];
    48     return res;
    49 }
    50 
    51 int main()
    52 {
    53     vector<int> arr{ 4,1,2,5,0,3,6,8 };
    54     vector<int> res = longestSequence(arr);
    55     for (int i = 0; i < res.size(); ++i)
    56         cout << res[i] << " ";
    57     cout << endl;
    58 
    59     return 0;
    60 }
    View Code

    9、最长连续递增子序列的长度

    Java实现:

    package com.mian.algorithm;
    
    public class LongestSerialSequence {
        public static void main(String[] args) {
            int[] arr={ 4,1,2,5,0,3,6,8 };
            System.out.println(longestSerialSequence(arr));
        }
        private static int longestSerialSequence(int[] arr){
            int size=arr.length;
            if(size==0||arr==null){
                return 0;
            }
            int curLen=1;
            int resLen=1;
            for(int i=1;i<size;++i){
                if(arr[i-1]<arr[i]){
                    ++curLen;
                    if(curLen>resLen){
                        resLen=curLen;
                    }
                }else{
                    curLen=1;
                }
            }
            int cur=1;
            for(int i=size-1;i>0;--i){
                if(arr[i]<arr[i-1]){
                    ++cur;
                    if(cur>resLen){
                        resLen=cur;
                    }
                }else{
                    cur=1;
                }
            }
            return resLen;
        }
    }
    View Code

    C++实现:

     1 int longestSerialSequence(vector<int> &arr)
     2 {
     3     int size = arr.size();
     4     if (size == 0 || arr.empty())
     5         return -1;
     6     int curLen = 1;
     7     int resLen = 1;
     8     for (int i = 1; i < size; ++i)
     9     {
    10         if (arr[i] > arr[i - 1])
    11             curLen++;
    12         else
    13             curLen = 1;
    14         if (curLen > resLen)
    15             resLen = curLen;
    16     }
    17     curLen = 1;
    18     for (int i = size - 1; i >= 1; --i)
    19     {
    20         if (arr[i] < arr[i - 1])
    21             curLen++;
    22         else
    23             curLen = 1;
    24         if (curLen > resLen)
    25             resLen = curLen;
    26     }
    27     return resLen;
    28 }
    View Code

    10、打印最长连续递增子序列

    Java实现:

    package com.mian.algorithm;
    
    public class PrintLongestSerialSequence {
        public static void main(String[] args) {
            int[] arr={ 4,1,2,5,0,3,6,8 };
            printLongestSerialSequence(arr);
        }
        private static void printLongestSerialSequence(int[] arr){
            int size=arr.length;
            if(size==0||arr==null){
                return;
            }
            int curLen=1;
            int resLen=1;
            int index=0;
            for(int i=1;i<size;++i){
                if(arr[i]>arr[i-1]){
                    ++curLen;
                    if(curLen>resLen){
                        resLen=curLen;
                        index=i;
                    }
                }else{
                    curLen=1;
                }
            }
            int i=index-resLen+1;
            while(resLen!=0){
                System.out.print(arr[i]+" ");
                ++i;
                --resLen;
            }
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 #include<vector>
     3 
     4 using namespace std;
     5 
     6 void longestSerialSequence(vector<int> &arr)
     7 {
     8     int size = arr.size();
     9     if (size == 0 || arr.empty())
    10         return;
    11     int curLen = 1;
    12     int resLen = 1;
    13     int index = 0;
    14     for (int i = 1; i < size; ++i)
    15     {
    16         if (arr[i] > arr[i - 1])
    17         {
    18             curLen++;
    19             index = i;
    20         }
    21         else
    22             curLen = 1;
    23         if (curLen > resLen)
    24             resLen = curLen;
    25     }
    26     int i = index - resLen + 1;
    27     while (resLen)
    28     {
    29         cout << arr[i] << " ";
    30         ++i;
    31         --resLen;
    32     }
    33     cout << endl;
    34 }
    35 
    36 int main()
    37 {
    38     vector<int> kk = { 2, 13, 6, 8, 9, 1 };
    39     longestSerialSequence(kk);
    40 
    41     return 0;
    42 }
    View Code

    11、最小的K个数
    输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。

    Java实现:

    package com.mian.algorithm;
    
    public class FindLowestK {
        public static void main(String[] args) {
            int[] arr={ 4, 5, 1, 6, 2, 7, 3, 8 };
            FindLowestK fk=new FindLowestK();
            int[] res=fk.findLowestK(arr,3);
            fk.printArray(res);
            int[] part=fk.findLowestKP(arr,3);
            fk.printArray(part);
        }
        //方法一:最大堆 时间复杂度O(nlogk)
        private int[] findLowestK(int[] arr,int k){
            int size=arr.length;
            if(size==0||arr==null||size<k||k<=0){
                return null;
            }
            int[] res=new int[k];
            for(int i=0;i<k;++i){
                res[i]=arr[i];
            }
            heapSort(res);
            for(int i=k;i<size;++i){
                if(res[k-1]>arr[i]){
                    res[k-1]=arr[i];
                    heapSort(res);
                }
            }
            return res;
        }
        private void heapSort(int[] arr){
            int size=arr.length;
            if(size==0||arr==null){
                return;
            }
            for(int i=size/2-1;i>=0;--i){
                adjustMaxHeap(arr,i,size);
            }
            for(int i=size-1;i>0;--i){
                swap(arr,0,i);
                adjustMaxHeap(arr,0,--size);
            }
        }
        private void adjustMaxHeap(int[] arr,int i,int size){
            int left=2*i+1;
            int right=2*i+2;
            int largest=i;
            if(left<size&&arr[left]>arr[largest]){
                largest=left;
            }
            if(right<size&&arr[right]>arr[largest]){
                largest=right;
            }
            if(largest!=i){
                swap(arr,i,largest);
                adjustMaxHeap(arr,largest,size);
            }
        }
        private void swap(int[] arr,int i,int j){
            int tmp=arr[i];
            arr[i]=arr[j];
            arr[j]=tmp;
        }
        //方法二:Partiton思想 时间复杂度O(n)
        private int[] findLowestKP(int[] arr,int k){
            int size=arr.length;
            if(size==0||arr==null){
                return null;
            }
            int low=0;
            int high=size-1;
            int index=partition(arr,low,high);
            while(index!=(k-1)){
                if(index>(k-1)){
                    high=index-1;
                    index=partition(arr,low,high);
                }else if(index<(k-1)){
                    low=index+1;
                    index=partition(arr,low,high);
                }
            }
            int[] res=new int[k];
            System.arraycopy(arr,0,res,0,k);
            return res;
        }
        private int partition(int[] arr,int low,int high){
            int pivot=arr[low];
            while(low<high){
                while(low<high&&arr[high]>=pivot){
                    --high;
                }
                arr[low]=arr[high];
                while(low<high&&arr[low]<=pivot){
                    ++low;
                }
                arr[high]=arr[low];
            }
            arr[low]=pivot;
            return low;
        }
        private void printArray(int[] arr){
            int size=arr.length;
            if(size==0||arr==null){
                return;
            }
            for(int i=0;i<size-1;++i){
                System.out.print(arr[i]+" ");
            }
            System.out.println(arr[size-1]);
        }
    }
    View Code

    C++实现:

    #include<iostream>
    #include<vector>
    #include<multiset>
    
    using namespace std;
    
    //方法一:最大堆 时间复杂度O(nlogk)
    void swap(vector<int> &arr, int i, int j)
    {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
    
    void adjustMaxHeap(vector<int> &arr, int i, int size)
    {
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        int largest = i;
        if (left<size&&arr[left]>arr[largest])
            largest = left;
        if (right<size&&arr[right]>arr[largest])
            largest = right;
        if (largest != i)
        {
            swap(arr, largest, i);
            adjustMaxHeap(arr, largest, size);
        }
    }
    
    void heapSort(vector<int> &arr)
    {
        int size = arr.size();
        if (arr.empty() || size == 0)
            return;
        for (int i = size / 2 - 1; i >= 0; --i)
            adjustMaxHeap(arr, i, size);
        for (int j = size - 1; j > 0; --j)
        {
            swap(arr, 0, j);
            adjustMaxHeap(arr, 0, --size);
        }
    }
    
    vector<int> findLowestK(vector<int> &arr, int k)
    {
        int size = arr.size();
        if (arr.empty() || size == 0 || size < k || k <= 0)
            return vector<int>();
        vector<int> res(k);
        /*
        vector<int>::iterator it = arr.begin();
        copy(it, it+k,res);
        */
            for (int i = 0; i < k; ++i)
                res[i] = arr[i];
            heapSort(res);
            for (int i = k; i < size; ++i)
                if (arr[i] < res[k - 1])
                {
                    res[k - 1] = arr[i];
                    heapSort(res);
                }
        return res;
    }
    
    //方法二:Partiton思想 时间复杂度O(n)
    int partition(vector<int> &arr, int low, int high)
    {
        int pivot = arr[low];
        while (low < high)
        {
            while (low < high&&pivot <= arr[high])
                --high;
            arr[low] = arr[high];
            while (low < high&&pivot >= arr[low])
                ++low;
            arr[high] = arr[low];
        }
        arr[low] = pivot;
        return low;
    }
    vector<int> findLowestK2(vector<int> &arr, int k)
    {
        int size = arr.size();
        if (size == 0 || arr.empty() || size < k || k <= 0)
            return vector<int>();
        int low = 0;
        int high = size - 1;
        int index = partition(arr, low, high);
        while (index != (k - 1))
        {
            if (index > (k - 1))
            {
                high = index - 1;
                partition(arr, low, high);
            }
            else
            {
                low = index + 1;
                partition(arr, low, high);
            }
        }
        return vector<int>(arr.begin(), arr.begin() + k);
    }
    //方法三:红黑树:multiset集合  利用仿函数改变排序顺序 时间复杂度O(nlogk)
    vector<int> findLowestK3(vector<int> &arr, int k)
    {
        int size = arr.size();
        if (size <= 0 || size < k || k <= 0)
            return vector<int>();
        //仿函数中的greater<T>模板,从大到小排序
        multiset<int, greater<int> > leastNums;
        vector<int>::iterator vec_it = input.begin();
        for (; vec_it != input.end(); vec_it++)
        {
            //将前k个元素插入集合
            if (leastNums.size()<k)
                leastNums.insert(*vec_it);
            else
            {
            //第一个元素是最大值
            multiset<int, greater<int> >::iterator greatest_it = leastNums.begin();
            //如果后续元素<第一个元素,删除第一个,加入当前元素
                if (*vec_it<*(leastNums.begin()))
                {
                    leastNums.erase(greatest_it);
                    leastNums.insert(*vec_it);
                }
        }
    }
    
        return vector<int>(leastNums.begin(), leastNums.end());
    }
    
    int main()
    {
        vector<int> ay = { 4, 5, 1, 6, 2, 7, 3, 8 };
        vector<int> fi = findLowestK(ay, 4);
        for (int i = 0; i < fi.size(); ++i)
            cout << fi[i] << " ";
        cout << endl;
        vector<int> fi2 = findLowestK2(ay, 4);
        for (int i = 0; i < fi2.size(); ++i)
            cout << fi[i] << " ";
        cout << endl;
        vector<int> fi3 = findLowestK3(ay, 4);
        for (int i = 0; i < fi3.size(); ++i)
            cout << fi[i] << " ";
        cout << endl;
    
        return 0;
    }
    View Code

    12、没有优先级的"+","-","x"

    Java实现:

    package com.mian.algorithm;
    
    import java.util.Scanner;
    
    public class NoPriority {
        public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            String str=sc.nextLine();
            int res=noPriority(str);
            System.out.println(res);
        }
        private static int noPriority(String str){
            int size=str.length();
            if(size==0||str.isEmpty()){
                return 0;
            }
            int res=str.charAt(0)-'0';
            for(int i=1;i<size;++i){
                int cur=str.charAt(i)-'0';
                if(cur>=0&&cur<=9){
                    char pre=str.charAt(i-1);
                    if(pre=='+'){
                        res+=cur;
                    }else if(pre=='-'){
                        res-=cur;
                    }else if(pre=='*'){
                        res*=cur;
                    }
                }
            }
            return res;
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 #include<string>
     3 
     4 using namespace std;
     5 
     6 void noPriority()
     7 {
     8     cout << "Enter a string:";
     9     string str;
    10     cin >> str;
    11     int size = str.size();
    12     if (str.empty()|| size == 0)
    13         return;
    14     int res = str[0] - '0';
    15     for (int i = 1; i < size; i++) {
    16         int cur = str[i] - '0';
    17         if (0 <= cur && cur <= 9) {
    18             char pre = str[i-1];
    19             if (pre == '+') {
    20                 res += cur;
    21             }
    22             else if (pre == '-') {
    23                 res -= cur;
    24             }
    25             else {
    26                 res *= cur;
    27             }
    28         }
    29     }
    30     cout << res << endl;
    31 }
    32 
    33 int main()
    34 {
    35     noPriority();
    36 
    37     return 0;
    38 }
    View Code

    13、在不使用循环的条件下,如何计算出一个数其2的n次方的最大数字(这个比较绕,例如17-->16,31-- >16)。

    Java实现:

    package com.mian.algorithm;
    
    public class Max2N {
        public static void main(String[] args) {
            System.out.println(max2N(31));
        }
        private static int max2N(int n){
            if((n>0)&&(n&(n-1))==0){
                return n;
            }
            return max2N(n-1);
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 
     3 using namespace std;
     4 
     5 int max2N(int n)
     6 {
     7     if ((n > 0) && (n&(n - 1)) == 0)
     8         return n;
     9     return max2N(n - 1);
    10 }
    11 
    12 int main()
    13 {
    14     cout << max2N(31) << endl;
    15 
    16     return 0;
    17 }
    View Code

    14、未排序数组中累加和为给定值的最长子数组的长度

    Java实现:

    package com.mian.algorithm;
    
    import java.util.HashMap;
    
    public class MaxLength {
        public static void main(String[] args) {
            int[] arr={ 1,2,1,1,1 };
            int target=3;
            System.out.println(maxLength(arr,target));
            System.out.println(maxLength2(arr,target));
        }
    
        /**
         * 0到位置i的累加和我们用sum[0~i],存在j使得sum[0~j] - sum[0~i] = k,则k = sum[i+1~j]
         * 补充题目1:给定一个无序数组 arr,其中元素可正、可负、可 0。
         * 求 arr 所有的子数组中正数与负数个数相等的最长子数组长度。
         * 要求:时间复杂度 O(N)
         * 分析:将数组中的正数变成1,负数变成-1,零仍然为零。然后求累加和为0的最长子数组,
         * 这样就将这个问题转化成未排序数组中累加和为给0的最长子数组问题了。
         * 补充题目2:给定一个无序数组 arr,其中元素只是 1 或 0。求 arr 所有的子数组中 0 和 1 个 数相等的最长子数组长度。
         * 要求:时间复杂度 O(N)
         * 分析:将数组中的0变成-1,1仍然为1,求累加和为0的最长子数组,可以求出1和-1个数相同,代表着0和1个数相同。
         *
         * 方法一:
         */
        private static int maxLength(int[] arr,int target){
            int size=arr.length;
            if(size==0||arr==null){
                return 0;
            }
            HashMap<Integer,Integer> map=new HashMap<>();
            map.put(0,-1);
            int len=0;
            int sum=0;
            for(int i=0;i<size;++i){
                sum+=arr[i];
                if(map.containsKey(sum-target)){
                    len=(i-map.get(sum-target))>len?(i-map.get(sum-target)):len;
                }
                if(!map.containsKey(sum)){
                    map.put(sum,i);
                }
            }
            return len;
        }
        /**
         * 方法二:使用两个指针left和right,记录从left到right之间的元素的值得和,使用一个变量len记录长度。
         * 如果这个和大于目标,那么left加1,如果这个和小于目标,那么right加1,如果这个值等于目标,那么比较并更新len,
         * 同时left++。right超过最右边的时候结束循环。
         */
        private static int maxLength2(int[] arr,int target){
            int size=arr.length;
            if(size==0||arr==null){
                return 0;
            }
            int left=0;
            int right=0;
            int len=0;
            int sum=0;
            while(right<size){
                if(sum<target){
                    ++right;
                    if(right==size){
                        break;
                    }
                    sum+=arr[right];
                }else if(sum>target){
                    sum+=arr[left++];
                }else{
                    len=Math.max(len,right-left+1);
                    sum-=arr[left++];
                }
            }
            return len;
        }
    }
    View Code

    C++实现:

    0到位置i的累加和我们用sum[0~i],存在j使得sum[0~j] - sum[0~i] = k,则k = sum[i+1~j]
    补充题目1:给定一个无序数组 arr,其中元素可正、可负、可 0。求 arr 所有的子数组中正数与负数个数相等的最长子数组长度。
    要求:时间复杂度 O(N)
    分析:将数组中的正数变成1,负数变成-1,零仍然为零。然后求累加和为0的最长子数组,这样就将这个问题转化成未排序数组中累加和为给0的最长子数组问题了。
    补充题目2:给定一个无序数组 arr,其中元素只是 1 或 0。求 arr 所有的子数组中 0 和 1 个 数相等的最长子数组长度。
    要求:时间复杂度 O(N)
    分析:将数组中的0变成-1,1仍然为1,求累加和为0的最长子数组,可以求出1和-1个数相同,代表着0和1个数相同。

    方法一:

     1 #include<iostream>
     2 #include<vector>
     3 #include<unordered_map>
     4 #include<algorithm>
     5 
     6 using namespace std;
     7 
     8 int maxLength(vector<int> &arr, int target)
     9 {
    10     int size = arr.size();
    11     if (size == 0 || arr.empty())
    12         return 0;
    13     unordered_map<int, int> m;
    14     m[0] = -1;
    15     int len = 0;
    16     int sum = 0;
    17     for (int i = 0; i < size; ++i)
    18     {
    19         sum += arr[i];
    20         auto it = m.find(sum - target);
    21         if (it != m.end())
    22             len = (i - m[sum - target]) > len ? (i - m[sum - target]) : len;
    23         auto p = m.find(sum);
    24         if (p == m.end())
    25             m[sum] = i;
    26     }
    27     return len;
    28 }
    29 
    30 int main()
    31 {
    32     vector<int> arr = { 1,2,1,1,1 };
    33     int target = 3;
    34     cout << maxLength(arr, target) << endl;
    35 
    36     return 0;
    37 }
    View Code

    方法二:使用两个指针left和right,记录从left到right之间的元素的值得和,使用一个变量len记录长度。如果这个和大于目标,那么left加1,如果这个和小于目标,那么right加1,如果这个值等于目标,那么比较并更新len,同时left++。right超过最右边的时候结束循环。

     1 #include<iostream>
     2 #include<vector>
     3 #include<unordered_map>
     4 #include<algorithm>
     5 
     6 using namespace std;
     7 
     8 int maxLen(vector<int> &arr, int target)
     9 {
    10     int size = arr.size();
    11     if (size == 0 || arr.empty())
    12         return 0;
    13     int left = 0, right = 0;
    14     int sum = 0;
    15     int len = 0;
    16     while (right < size)
    17     {
    18         if (sum < target)
    19         {
    20             ++right;
    21             if (right == size)
    22                 break;
    23             sum += arr[right];
    24         }
    25         else if (sum > target)
    26             sum += arr[left++];
    27         else
    28         {
    29             len = max(len, right - left + 1);
    30             sum -= arr[left++];
    31         }
    32     }
    33     return len;
    34 }
    35 
    36 int main()
    37 {
    38     vector<int> arr = { 1,2,1,1,1 };
    39     int target = 3;
    40     cout << maxLen(arr, target) << endl;
    41 
    42     return 0;
    43 }
    View Code

    15、连续子序列的最大和

    Java实现:

    package com.mian.algorithm;
    
    public class MaxSum {
        public static void main(String[] args) {
            int[] arr={ 6,-3,-2,7,-15,1,2,2 };
            System.out.println(maxSum(arr));
            System.out.println(maxSum2(arr));
        }
    
        /**
         * 方法一:连续子序列的最大和只可能是以位置0~n-1中某个位置结尾。当遍历到第i个元素时,
         * 判断在它前面的连续子序列和是否大于0,如果大于0,则以位置i结尾的最大连续子序列和为元素i和前门的连续子序列和相加;
         * 否则,则以位置i结尾的最大连续子序列和为元素i。
         */
        private static int maxSum(int[] arr){
            int size=arr.length;
            if(size==0||arr==null){
                return 0;
            }
            int curSum=arr[0];
            int maxSum=arr[0];
            for(int i=1;i<size;++i){
                if(curSum<0){
                    curSum=arr[i];
                }else{
                    curSum+=arr[i];
                }
                if(curSum>maxSum){
                    maxSum=curSum;
                }
            }
            return maxSum;
        }
        /**
         * 方法二:暴力解。时间复杂度O(n^2),空间复杂度O(1)。
         */
        private static int maxSum2(int[] arr){
            int size=arr.length;
            if(size==0||arr==null){
                return 0;
            }
            int maxSum=Integer.MIN_VALUE;
            for(int i=0;i<size;++i){
                int curSum=0;
                for(int j=i;j<size;++j){
                    curSum+=arr[j];
                    if(curSum>maxSum){
                        maxSum=curSum;
                    }
                }
            }
            return maxSum;
        }
    }
    View Code

    C++实现:

    方法一:连续子序列的最大和只可能是以位置0~n-1中某个位置结尾。当遍历到第i个元素时,判断在它前面的连续子序列和是否大于0,如果大于0,则以位置i结尾的最大连续子序列和为元素i和前门的连续子序列和相加;否则,则以位置i结尾的最大连续子序列和为元素i。

     1 #include<iostream>
     2 #include<vector>
     3 
     4 using namespace std;
     5 
     6 int maxSum(vector<int> &arr)
     7 {
     8     int size = arr.size();
     9     if (size == 0 || arr.empty())
    10         return -1;
    11     int max = arr[0];
    12     int cur = arr[0];
    13     for (int i = 1; i < size; ++i)
    14     {
    15         if (cur <= 0)
    16             cur = arr[i];
    17         else
    18             cur += arr[i];
    19         if (cur > max)
    20             max = cur;
    21     }
    22     return max;
    23 }
    24 
    25 int main()
    26 {
    27     vector<int> arr = { 6,-3,-2,7,-15,1,2,2 };
    28     cout << maxSum(arr) << endl;
    29 
    30     return 0;
    31 }
    View Code

    方法二:暴力解。时间复杂度O(n^2),空间复杂度O(1)。

     1 #include<iostream>
     2 #include<vector>
     3 
     4 using namespace std;
     5 
     6 int maxSum(vector<int> &arr)
     7 {
     8     int size = arr.size();
     9     if (size == 0 || arr.empty())
    10         return -1;
    11     int max = INT_MIN;
    12     for (int i = 0; i < size; ++i)
    13     {
    14         int sum = 0;
    15         for (int j = i; j < size; ++j)
    16         {
    17             sum += arr[j];
    18             if (sum > max)
    19                 max = sum;
    20         }
    21     }
    22     return max;
    23 }
    24 
    25 int main()
    26 {
    27     vector<int> arr = { 6,-3,-2,7,-15,1,2,2 };
    28     cout << maxSum(arr) << endl;
    29 
    30     return 0;
    31 }
    View Code

    16、合并两个有序数组

    Java实现:

    package com.mian.algorithm;
    
    public class MergeArray {
        public static void main(String[] args) {
            int[] arr1={ 0,3,5,6,7,9 };
            int[] arr2= { 2,3,4,7,8,9 };
            int[] res=mergeArray(arr1,arr2);
            printArray(res);
            int[] res2=mergeArray2(arr1,arr2);
            printArray(res2);
        }
        private static int[] mergeArray(int[] arr1,int[] arr2){
            int size1=arr1.length;
            int size2=arr2.length;
            if(size1==0||arr1==null){
                return arr2;
            }
            if(size2==0||arr2==null){
                return arr1;
            }
            if((size1==0&&size2==0)||(arr1==null&&arr2==null)){
                return null;
            }
            int i=0,j=0,k=0;
            int[] res=new int[size1+size2];
            while (i<size1&&j<size2){
                if(arr1[i]<arr2[j]){
                    res[k++]=arr1[i++];
                }else{
                    res[k++]=arr2[j++];
                }
            }
            while(i<size1){
                res[k++]=arr1[i++];
            }
            while(j<size2){
                res[k++]=arr2[j++];
            }
            return res;
        }
        private static int[] mergeArray2(int[] arr1,int[] arr2){
            int size1=arr1.length;
            int size2=arr2.length;
            if(size1==0||arr1==null){
                return arr2;
            }
            if(size2==0||arr2==null){
                return arr1;
            }
            if((size1==0&&size2==0)||(arr1==null&&arr2==null)){
                return null;
            }
            int i=0,j=0,k=0;
            int[] res=new int[size1+size2];
            while(i<size1&&j<size2){
                if(arr1[i]<arr2[j]){
                    res[k++]=arr1[i++];
                }else if(arr1[i]>arr2[j]){
                    res[k++]=arr2[j++];
                }else{
                    res[k++]=arr1[i++];
                    res[k++]=arr2[j++];
                }
            }
            while(i<size1){
                res[k++]=arr1[i++];
            }
            while(j<size2){
                res[k++]=arr2[j++];
            }
            return res;
        }
        private static void printArray(int[] arr){
            int size=arr.length;
            if(size==0||arr==null){
                return;
            }
            for(int i=0;i<size-1;++i){
                System.out.print(arr[i]+" ");
            }
            System.out.println(arr[size-1]);
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 #include<vector>
     3 
     4 using namespace std;
     5 
     6 vector<int> mergeArray(vector<int> &arr1, vector<int> &arr2)
     7 {
     8     int size1 = arr1.size();
     9     int size2 = arr2.size();
    10     if (size1 == 0 || size2 == 0 || arr1.empty() || arr2.empty())
    11         return vector<int>();
    12     vector<int> res(size1 + size2);
    13     int i = 0, j = 0, k = 0;
    14     while (i < size1&&j < size2)
    15     {
    16         if (arr1[i] < arr2[j])
    17             res[k++] = arr1[i++];
    18         else if (arr1[i] > arr2[j])
    19             res[k++] = arr2[j++];
    20         else
    21         {
    22             res[k++] = arr1[i++];
    23             res[k++] = arr2[j++];
    24         }
    25     }
    26     while (i < size1)
    27         res[k++] = arr1[i++];
    28     while (j < size2)
    29         res[k++] = arr2[j++];
    30     return res;
    31 }
    32 
    33 int main()
    34 {
    35     vector<int> arr1 = { 0,3,5,6,7,9 };
    36     vector<int> arr2 = { 2,3,4,7,8,9 };
    37     vector<int> res = mergeArray(arr1, arr2);
    38     for (int i = 0; i < res.size(); ++i)
    39         cout << res[i] << " ";
    40     cout << endl;
    41 
    42     return 0;
    43 }
    View Code

    17、旋转数组的最小数字

    Java实现:

    package com.mian.algorithm;
    
    public class MinNumberInRotateArray {
        public static void main(String[] args) {
            int[] arr={1,0,1,1,1};
            System.out.println(minNumberInRotateArray(arr));
        }
        private static int minNumberInRotateArray(int[] arr){
            int size=arr.length;
            if(size==0||arr==null){
                return 0;
            }
            int low=0;
            int high=size-1;
            int mid=low;
            while(arr[low]>=arr[high]){
                if(high-low==1){
                    mid=high;
                    break;
                }
                mid=(low+high)>>1;
                if(arr[low]==arr[mid]&&arr[mid]==arr[high]){
                    int min=arr[low];
                    for(int i=low+1;i<=high;++i){
                        if(min>arr[i]){
                            min=arr[i];
                        }
                    }
                    return min;
                }else if(arr[low]>=arr[mid]){
                    low=mid;
                }else if(arr[mid]<=arr[high]){
                    high=mid;
                }
            }
            return arr[mid];
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 #include<vector>
     3 
     4 using namespace std;
     5 
     6 int minNumberInRotateArray(vector<int> arr) {
     7     int low = 0;
     8     int high = arr.size() - 1;
     9     int mid = low;
    10     while (arr[low] >= arr[high])
    11     {
    12         if (high - low == 1)
    13         {
    14             mid = high;
    15             break;
    16         }
    17         mid = (low + high) / 2;
    18         if (arr[low] == arr[mid] && arr[mid] == arr[high])
    19         {
    20             int min = arr[low];
    21             for (int i = low + 1; i <= high; ++i)
    22                 if (min>arr[i])
    23                     min = arr[i];
    24             return min;
    25         }
    26         if (arr[mid] >= arr[low])
    27             low = mid;
    28         else if (arr[mid] <= arr[high])
    29             high = mid;
    30     }
    31     return arr[mid];
    32 }
    33 
    34 int main()
    35 {
    36     vector<int> arr = {1,0,1,1,1};
    37     cout << minNumberInRotateArray(arr) << endl;
    38 
    39     return 0;
    40 }
    View Code

    18、数组中出现次数超过一半的数字
    数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。
    由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

    Java实现:

    package com.mian.algorithm;
    
    import java.util.HashMap;
    
    public class MoreHalf {
        public static void main(String[] args) {
            int[] arr={1,2,3,2,2,2,5,4,2};
            System.out.println(moreHalf(arr));
            System.out.println(moreHalf2(arr));
            System.out.println(moreHalf3(arr));
        }
        private static int moreHalf(int[] arr){
            int size=arr.length;
            if(size==0||arr==null){
                return Integer.MIN_VALUE;
            }
            int cnt=0;
            int res=0;
            for(int i=0;i<size;++i){
                if(cnt==0){
                    res=arr[i];
                    ++cnt;
                }else{
                    if(res==arr[i]){
                        ++cnt;
                    }else{
                        --cnt;
                    }
                }
            }
            cnt=0;
            for(int i=0;i<size;++i){
                if(arr[i]==res){
                    ++cnt;
                }
            }
            if(cnt>size/2){
                return res;
            }
            return Integer.MIN_VALUE;
        }
        private static int moreHalf2(int[] arr){
            int size=arr.length;
            if(size==0||arr==null){
                return Integer.MIN_VALUE;
            }
            int res=Integer.MIN_VALUE;
            HashMap<Integer,Integer> map=new HashMap<>();
            for(int i=0;i<size;++i){
                if(map.containsKey(arr[i])){
                    map.put(arr[i],map.get(arr[i])+1);
                }else{
                    map.put(arr[i],1);
                }
                if(map.get(arr[i])>size/2){
                    res=arr[i];
                }
            }
            int cnt=0;
            for(int i=0;i<size;++i){
                if(arr[i]==res){
                    ++cnt;
                }
            }
            if(cnt>size/2){
                return res;
            }
            return Integer.MIN_VALUE;
        }
        private static int moreHalf3(int[] arr){
            int size=arr.length;
            if(size==0||arr==null){
                return Integer.MIN_VALUE;
            }
            int mid=size>>1;
            int low=0;
            int high=size-1;
            int index=partition(arr,low,high);
            while(index!=mid){
                if(index>mid){
                    high=index-1;
                    index=partition(arr,low,high);
                }else if(index<mid){
                    low=index+1;
                    index=partition(arr,low,high);
                }
            }
            int res=arr[mid];
            int cnt=0;
            for(int i=0;i<size;++i){
                if(arr[i]==res){
                    ++cnt;
                }
            }
            if(2*cnt>size){
                return res;
            }else{
                return Integer.MIN_VALUE;
            }
        }
        private static int partition(int[] arr,int low,int high){
            int pivot=arr[low];
            while(low<high){
                while(low<high&&arr[high]>=pivot){
                    --high;
                }
                arr[low]=arr[high];
                while(low<high&&arr[low]<=pivot){
                    ++low;
                }
                arr[high]=arr[low];
            }
            arr[low]=pivot;
            return low;
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 #include<vector>
     3 
     4 using namespace std;
     5 
     6 int moreHalf(vector<int> &arr)
     7 {
     8     int size = arr.size();
     9     if (size == 0 || arr.empty())
    10         return -1;
    11     int candi = 0;
    12     int cnt = 0;
    13     for (int i = 0; i < size; ++i)
    14     {
    15         if (cnt == 0)
    16         {
    17             candi = arr[i];
    18             ++cnt;
    19         }
    20         else
    21         {
    22             if (arr[i] == candi)
    23                 ++cnt;
    24             else
    25                 --cnt;
    26         }
    27     }
    28     return candi;
    29 }
    30 
    31 int main()
    32 {
    33     vector<int> arr = { 8,0,2,3,1,2,2,1,2,2 };
    34     cout << moreHalf(arr) << endl;
    35 
    36     return 0;
    37 }
    View Code

    19、某一范围内的整数包含1的数量

    Java实现:

    package com.mian.algorithm;
    
    public class NumberOf1Between1AndN {
        public static void main(String[] args) {
            System.out.println(numberOf1Between1AndN(34278));
            System.out.println(numberOf1Between1AndN2(34278));
        }
    
        /**
         * 方法一:暴力解
         */
        private static int numberOf1Between1AndN(int n){
            if(n<0){
                return 0;
            }
            if(n<9){
                return 1;
            }
            int cnt=1;
            for(int i=10;i<=n;++i){
                int tmp=i;
                while(tmp!=0){
                    if(tmp%10==1){
                        ++cnt;
                    }
                    tmp/=10;
                }
            }
            return cnt;
        }
        private static int numberOf1Between1AndN2(int n){
            int cnt = 0;
            for (int m = 1; m <= n; m *= 10){
                int a = n / m, b = n%m;
                if (a % 10 == 0){
                    cnt+=a/10*m;
                }else if (a % 10 == 1) {
                    cnt += a / 10 * m + (b + 1);
                }else{
                    cnt += (a / 10 + 1)*m;
                }
            }
            return cnt;
        }
    }
    View Code

    C++实现:

    方法一:暴力解

     1 #include<iostream>
     2 
     3 using namespace std;
     4 
     5 int NumberOf1Between1AndN(int n)
     6 {
     7     if (n <= 0)
     8         return 0;
     9     if (n < 9)
    10         return 1;
    11     int cnt = 1;
    12     for (int i = 10; i <= n; ++i)
    13     {
    14         int tmp = i;
    15         while (tmp)
    16         {
    17             if (tmp % 10 == 1)
    18                 ++cnt;
    19             tmp /= 10;
    20         }
    21     }
    22     return cnt;
    23 }
    24 
    25 int main()
    26 {
    27     cout << NumberOf1Between1AndN(34278) << endl;
    28 
    29     return 0;
    30 }
    View Code

    方法二:

     1 #include<iostream>
     2 
     3 using namespace std;
     4 
     5 int NumberOf1Between1AndN(int n)
     6 {
     7     int cnt = 0;
     8     for (int m = 1; m <= n; m *= 10)
     9     {
    10         int a = n / m, b = n%m;
    11         if (a % 10 == 0)
    12             cnt += a / 10 * m;
    13         else if (a % 10 == 1)
    14             cnt += a / 10 * m + (b + 1);
    15         else
    16             cnt += (a / 10 + 1)*m;
    17     }
    18     return cnt;
    19 }
    20 
    21 int main()
    22 {
    23     cout << NumberOf1Between1AndN(34278) << endl;
    24 
    25     return 0;
    26 }
    View Code

    20、N的阶乘二进制表示的最低位1的位置
    这个问题实际上等同于求N!含有质因数2的个数+1。即答案等于N!含有质因数2的个数加1。 如果一个质数是某个数的因数,那么就说这个质数是这个数的质因数。
    因为每存在一个2,则在数的最低位多1个0。实际上N!都为偶数,因为质因数里面都有一个2,
    除了1以外,因为1的阶乘是1,是个奇数,其他数的阶乘都是偶数。

    Java实现:

    package com.mian.algorithm;
    
    public class PosOfOneBinary {
        public static void main(String[] args) {
            System.out.println(posOfOneBinary(3));
        }
        private static int posOfOneBinary(int n){
            if(n<0){
                return -1;
            }
            int res=0;
            while(n!=0){
                n>>=1;
                res+=n;
            }
            return (res+1);
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 
     3 using namespace std;
     4 
     5 int posOfOneBinary(int n)
     6 {
     7     if (n < 0)
     8         return -1;
     9     int res = 0;
    10     while (n)
    11     {
    12         n >>= 1;
    13         res += n;
    14     }
    15     
    16     return (res + 1);
    17 }
    18 
    19 int main()
    20 {
    21     cout << posOfOneBinary(3) << endl;
    22 
    23     return 0;
    24 }
    View Code

    21、输入一个正整数N,输出大于N且最接近这个数的素数

    Java实现:

    package com.mian.algorithm;
    
    public class FindPrime {
        public static void main(String[] args) {
            FindPrime findPrime=new FindPrime();
            findPrime.findPrime(34);
        }
        private static void findPrime(int n){
            if(n<=1){
                System.out.println(2);
            }
            while(n>0){
                if(!isPrime(n)){
                    ++n;
                }else{
                    System.out.println(n);
                    break;
                }
            }
        }
        private static boolean isPrime(int n){
            if(n==0||n==1){
                return false;
            }
            for(int i=2;i<Math.sqrt(n);++i){
                if(n%i==0){
                    return false;
                }
            }
            return true;
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 #include<algorithm>
     3 
     4 using namespace std;
     5 
     6 bool isPrime(int n)
     7 {
     8     if (n == 0 || n == 1)
     9         return false;
    10     for (int i = 2; i <= sqrt(n); ++i)
    11         if (n%i == 0)
    12             return false;
    13     return true;
    14 }
    15 
    16 void findPrime(int n)
    17 {
    18     if (n <= 0)
    19         return;
    20     while (n > 0)
    21         if (!isPrime(n))
    22             ++n;
    23         else
    24         {
    25             cout << n << endl;
    26             break;
    27         }
    28 }
    29 
    30 int main()
    31 {
    32     findPrime(34);
    33 
    34     return 0;
    35 }
    View Code

    22、读取文件,每一行有一个字段为数字,按数字大小排序,输出整个文档

    Java实现:

    package com.mian.algorithm;
    
    import java.io.*;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;
    
    public class ReadWriteFile {
        public static void main(String[] args)throws IOException{
            ReadWriteFile rwf=new ReadWriteFile();
            rwf.readWriteFile("D:/lina/in.txt","D:/lina/out.txt");
        }
        private void readWriteFile(String in,String out){
            File inFile=null;
            BufferedReader br=null;
            List<Integer> nums=new ArrayList<>();
            try{
                inFile=new File(in);
                if(!inFile.exists()||inFile.isDirectory()){
                    System.out.println("读入文件不存在!!!");
                }
                br=new BufferedReader(new FileReader(inFile));
                String tmp=br.readLine();
                while(tmp!=null){
                    nums.add(Integer.parseInt(tmp));
                    System.out.print(tmp+"	");
                    tmp=br.readLine();
                }
            }catch (IOException e){
                e.printStackTrace();
            }finally {
                try {
                    br.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
    
            Collections.sort(nums,(a,b)->a.compareTo(b));
            BufferedWriter bw = null;
            try {
                File file = new File(out);
                if (!file.exists()) {
                    file.createNewFile();
                }
                FileWriter fw = new FileWriter(file.getAbsoluteFile());
                bw = new BufferedWriter(fw);
                for(int i=0;i<nums.size();++i){
                    bw.write(nums.get(i).toString());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    bw.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 #include<fstream>
     3 #include<vector>
     4 #include<algorithm>
     5 #include<string>
     6 
     7 using namespace std;
     8 
     9 void readWriteFile(string &in,string &out)
    10 {
    11     ifstream infile(in);
    12     if (!infile.is_open())
    13     {
    14         cout << "can not open" << in << endl;
    15         EXIT_FAILURE;
    16     }
    17     vector<int> res;
    18     int tmp;
    19     while (!infile.eof())
    20     {
    21         infile >> tmp;
    22         res.push_back(tmp);
    23     }
    24     infile.close();
    25     sort(res.begin(), res.end());
    26     for (int i = 0; i < res.size(); ++i)
    27         cout << res[i] << " ";
    28     cout << endl;
    29     ofstream outfile(out, 'w');
    30     if (!outfile.is_open())
    31     {
    32         cout << "can not open" << out << endl;
    33         EXIT_FAILURE;
    34     }
    35     vector<int>::iterator it = res.begin();
    36     while (it != res.cend())
    37         outfile << *it++;
    38     outfile.close();
    39 }
    40 
    41 int main()
    42 {
    43     string in = "num.txt";
    44     string out = "sort.txt";
    45     readWriteFile(in, out);
    46 }
    View Code

    23、找出数组中重复的数
    在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。

    Java实现:

    package com.mian.algorithm;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class DuplicateNum {
        public static void main(String[] args) {
            DuplicateNum dn=new DuplicateNum();
            int[] arr={ 2,3,1,0,2,5,3 };
            List<Integer> res=dn.duplicateNum(arr);
            for(int i=0;i<res.size();++i){
                System.out.print(res.get(i)+" ");
            }
        }
        private List<Integer> duplicateNum(int[] arr){
            int size=arr.length;
            if(size==0||arr==null){
                return null;
            }
            List<Integer> res=new ArrayList<>();
            int[] hash=new int[size];
            for(int i=0;i<size;++i){
                hash[arr[i]]++;
                if(hash[arr[i]]>1){
                    res.add(arr[i]);
                }
            }
            return res;
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 #include<vector>
     3 
     4 using namespace std;
     5 
     6 vector<int> duplicateNum(vector<int> &arr)
     7 {
     8     int size = arr.size();
     9     if (arr.empty() || size == 0)
    10         return vector<int>();
    11     vector<int> hash(size);
    12     vector<int> res;
    13     for (int i = 0; i < size; ++i)
    14     {
    15         hash[arr[i]]++;
    16         if (hash[arr[i]] > 1)
    17             res.push_back(arr[i]);
    18     }
    19     return res;
    20 }
    21 
    22 int main()
    23 {
    24     vector<int> arr = { 2,3,1,0,2,5,3 };
    25     vector<int> res = duplicateNum(arr);
    26     for (int i = 0; i < res.size(); ++i)
    27         cout << res[i] << " ";
    28     cout << endl;
    29 
    30     return 0;
    31 }
    View Code

    24、反转双链表

    Java实现:

    package com.mian.algorithm;
    
    import java.util.Scanner;
    
    public class ReverseDoubleList {
        public static void main(String[] args) {
            ReverseDoubleList rdl=new ReverseDoubleList();
            DoubleListNode head=rdl.createDoubleList();
            rdl.printDoubleList(head);
            System.out.println("------------------");
           DoubleListNode last= rdl.reverseDoubleList(head);
            rdl.printDoubleList(last);
        }
        private DoubleListNode createDoubleList(){
            int val;
            DoubleListNode head=null;
            DoubleListNode cur=null;
            DoubleListNode pre=null;
            System.out.println("enter list value (enter 100 to quit):");
            Scanner sc=new Scanner(System.in);
            val=sc.nextInt();
            while(val!=100){
                cur=new DoubleListNode(val);
                if(head==null){
                    head=cur;
                }
                if(pre==null) {
                    cur.last=null;
                    cur.next=null;
                }else{
                    cur.last=pre;
                    pre.next=cur;
                }
                pre=cur;
                System.out.println("enter list value (enter 100 to quit):");
                val=sc.nextInt();
            }
            return head;
        }
        private DoubleListNode reverseDoubleList(DoubleListNode head){
            if(head==null){
                return head;
            }
            DoubleListNode pre=null;
            DoubleListNode next=null;
            while(head!=null){
                next=head.next;
                head.next=pre;
                head.last=next;
                pre=head;
                head=next;
            }
            return pre;
        }
        private void printDoubleList(DoubleListNode head){
            if(head==null){
                return;
            }
            DoubleListNode cur=head;
            while(cur.next!=null){
                System.out.print(cur.val+" ");
                cur=cur.next;
            }
            System.out.println(cur.val);
            while(cur!=null){
                System.out.print(cur.val+" ");
                cur=cur.last;
            }
            System.out.println();
        }
    }
    
    class DoubleListNode{
        public int val;
        DoubleListNode next;
        DoubleListNode last;
        DoubleListNode(){}
        DoubleListNode(int v){
            this.val=v;
            this.next=null;
            this.last=null;
        }
    }
    View Code

    C++实现:

     1 class DoubleListNode {
     2 public:
     3     int val;
     4     DoubleListNode *next;
     5     DoubleListNode *last;
     6     DoubleListNode(int v):val(v),next(nullptr),last(nullptr){}
     7 };
     8 
     9 DoubleListNode *reverseDoubleList(DoubleListNode *head)
    10 {
    11     if (head == nullptr)
    12         return head;
    13     DoubleListNode *pre = nullptr;
    14     DoubleListNode *next = nullptr;
    15     while (head)
    16     {
    17         next = head->next;
    18         head->next = pre;
    19         head->last = next;
    20         pre = head;
    21         head = next;
    22     }
    23     return pre;
    24 }
    View Code

    25、字符串转整数

    Java实现:

    package com.mian.algorithm;
    
    public class MyAtoi {
        public static void main(String[] args){
    
        }
        private int myAtoi(String str){
            str = str.trim();
            if(str.isEmpty()){
                return 0;
            }
            boolean isPositive = true;
            long num = 0;
            int i = 0;
            char firstChar = str.charAt(0);
            if(Character.isDigit(firstChar)) {
                i = 0;
                isPositive = true;
            }else if (firstChar == '+') {
                i = 1;
                isPositive = true;
            }else if (firstChar == '-'){
                i = 1;
                isPositive = false;
            }
            char c;
            for(; i < str.length(); i++) {
                c = str.charAt(i);
                if(Character.isDigit(c) && num < Integer.MAX_VALUE){
                    num = num * 10 + (c - '0');
                }
                else{
                    break;
                }
            }
            if(!isPositive) {
                num*=-1;
            }
            if(num < Integer.MIN_VALUE){
                return Integer.MIN_VALUE;
            }else if(num > Integer.MAX_VALUE){
                return Integer.MAX_VALUE;
            }else{
                return (int)num;
            }
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 #include<string>
     3 
     4 using namespace std;
     5 
     6 int myAtoi(string &str)
     7 {
     8     if (str.empty())
     9         return 0;
    10     int sign = 1, base = 0, i = 0, n = str.size();
    11     while (i < n&&str[i] == ' ')
    12         ++i;
    13     if (str[i] == '+' || str[i] == '-')
    14         sign = (str[i++] == '+') ? 1 : -1;
    15     while (i < n&&str[i] >= '0'&&str[i] <= '9')
    16     {
    17         if (base > INT_MAX / 10 || (base == INT_MAX / 10 && str[i] - '0' > 7))
    18             return (sign == 1) ? INT_MAX : INT_MIN;
    19         base = 10 * base + (str[i++] - '0');
    20     }
    21     return base*sign;
    22 }
    23 
    24 int main()
    25 {
    26     string str = "-98384";
    27     cout << myAtoi(str) << endl;
    28 
    29     return 0;
    30 }
    View Code

    26、字符串转换float

    Java实现:

    package com.mian.algorithm;
    
    public class StringToFloat {
        public static void main(String[] args) {
            StringToFloat stf=new StringToFloat();
            float res=stf.stringToFloat("89.432");
            System.out.println(res);
        }
        private float stringToFloat(String str){
            int size=str.length();
            if(str.isEmpty()||size==0){
                return Float.MIN_VALUE;
            }
            float res=0;
            int sign=1;
            if(str.charAt(0)=='+'){
                sign=1;
            }else if(str.charAt(0)=='-'){
                sign=-1;
            }else if(str.charAt(0)>='0'&&str.charAt(0)<='9'){
                res+=str.charAt(0)-'0';
            }else{
                return Float.MIN_VALUE;
            }
            int index=str.indexOf('.');
            for(int i=1;i<index;++i){
                if(str.charAt(i)<'0'||str.charAt(i)>'9'){
                    return Float.MIN_VALUE;
                }
                res=res*10+(str.charAt(i)-'0');
            }
            float total=0;
            for(int i=index+1;i<size;++i){
                if(str.charAt(i)<'0'||str.charAt(i)>'9'){
                    return Float.MIN_VALUE;
                }
                total=total*10+(str.charAt(i)-'0');
            }
            int pos=1;
            for(int i=0;i<(size-index-1);++i){
                pos*=10;
            }
            total=total/pos;
            return sign==1?(res+total):-(res+total);
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 #include<string>
     3 
     4 using namespace std;
     5 
     6 float str2float(string &str)
     7 {
     8     int size = str.size();
     9     if (str.empty() || size == 0)
    10         return FLT_MIN;
    11     float sum = 0;
    12     int sign = 1;
    13     if (str[0] == '+')
    14         sign = 1;
    15     else if (str[0] == '-')
    16         sign = -1;
    17     else if (str[0] >= '0'&&str[0] <= '9')
    18         sum = str[0] - '0';
    19     else
    20         return FLT_MIN;
    21     size_t pos = str.find('.');
    22     cout << pos << endl;
    23     for (int i = 1; i < pos; ++i)
    24     {
    25         if (str[i]<'0' || str[i]>'9')
    26             return FLT_MIN;
    27         sum = sum * 10 + str[i] - '0';
    28     }
    29     float total = 0;
    30     for (int i = pos + 1; i < size; ++i)
    31     {
    32         if (str[i]<'0' || str[i]>'9')
    33             return FLT_MIN;
    34         total = total * 10 + str[i] - '0';
    35     }
    36     total = total / (pow(10,(size-pos-1)));
    37         return sign == 1 ? (sum + total) : -(sum + total);
    38 }
    39 
    40 int main()
    41 {
    42     string str = "89.432";
    43     cout << str2float(str) << endl;
    44 
    45     return 0;
    46 }
    View Code

    27、字符串数组的字符串是否都能首尾相接

    Java实现:

    package com.mian.algorithm;
    
    import java.util.Arrays;
    
    public class StrOrgEnd {
        public static void main(String[] args){
            String [] str = {"gj","jl","dg","ad","gg"};
            StrOrgEnd  sre=new StrOrgEnd();
            sre.strOrgEnd(str,0);
            sre.strOrgEnd2(str,0);
        }
        private void strOrgEnd(String[] str,int k){
            if(k==str.length){
                System.out.println(Arrays.toString(str));
                return;
            }
            for(int i=k;i<str.length;++i){
                /**
                 *  交换k+1和i
                 *  k=0,表明为第一个字符串,必须和自己以及后面每一个交换
                 *  k>0时,假设0-(k-1)是排序好的,我们需比较k-1和i的顺序
                 */
                if((k>0&&judge(str[k-1],str[i]))||k==0){
                    swap(str,k,i);
                    strOrgEnd(str,k+1);
                    swap(str,k,i);
                }
            }
        }
        private void strOrgEnd2(String[] str,int k){
            if(k==str.length){
                System.out.println(Arrays.toString(str));
                return;
            }
            for(int i=k;i<str.length;++i){
                if(k>0&&judge(str[k-1],str[i])){
                    swap(str,k,i);
                    strOrgEnd(str,k+1);
                    swap(str,k,i);
                }else if(k==0){
                    swap(str,k,i);
                    strOrgEnd(str,k+1);
                    swap(str,k,i);
                }
            }
        }
        private boolean judge(String str1,String str2){
            if(str1.charAt(str1.length()-1)==str2.charAt(0)){
                return true;
            }
            return false;
        }
        private void swap(String[] str,int i,int j){
            String tmp=str[i];
            str[i]=str[j];
            str[j]=tmp;
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 #include<string>
     3 #include<vector>
     4 
     5 using namespace std;
     6 
     7 void swap(vector<string> &arr, int i, int j)
     8 {
     9     string tmp = arr[i];
    10     arr[i] = arr[j];
    11     arr[j] = tmp;
    12 }
    13 
    14 bool judge(string &s1, string &s2)
    15 {
    16     if (s1[s1.size() - 1] == s2[0])
    17         return true;
    18     return false;
    19 }
    20 
    21 void fun(vector<string> &arr, int k)
    22 {
    23     int size = arr.size();
    24     if (k == size)
    25     {
    26         for (int i = 0; i < size; ++i)
    27             cout << arr[i] << " ";
    28         cout << endl;
    29     }
    30     for (int i = k; i < size; ++i)
    31     {
    32         // k>0时,之前的0-k-1个字符串已经排好序,则判断k-1号字符串与之后的字符串
    33         if (k > 0 && judge(arr[k - 1], arr[i]))
    34         {
    35             swap(arr, k, i);
    36             fun(arr, k + 1);
    37             swap(arr, k, i);
    38         }
    39         else if (k == 0)// k=0,表明为第一个字符串,必须和自己以及后面每一个交换并作出判断
    40         {
    41             swap(arr, k, i);
    42             fun(arr, k + 1);
    43             swap(arr, k, i);
    44         }
    45     }
    46 }
    47 
    48 int main()
    49 {
    50     vector<string> arr = { "gj", "jl", "dg", "ad", "gg" };
    51     fun(arr, 0);
    52 
    53     return 0;
    54 }
    View Code

    28、递归求和

    Java实现:

    package com.mian.algorithm;
    
    public class SumWithRecur {
        public static void main(String[] args){
            SumWithRecur sw=new SumWithRecur();
            int sum=sw.sumWithRecur(5);
            System.out.println(sum);
        }
        private int sumWithRecur(int n){
            if(n==1){
                return 1;
            }
            return sumWithRecur(n-1)+n;
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 
     3 using namespace std;
     4 
     5 int sumWithRecur(int n)
     6 {
     7     if (n == 1)
     8         return 1;
     9     return sumWithRecur(n - 1) + n;
    10 }
    11 
    12 int main()
    13 {
    14     cout << sumWithRecur(5);
    15 
    16     return 0;
    17 }
    View Code

    29、交替打印数组
    已知一个数组a1,a2,... an,b1,b2,...,bn,设计一个算法把数组变成a1,b1,a2,b2,...,an,bn。

    Java实现:

    package com.mian.algorithm;
    
    public class SwapPrintArray {
        public static void main(String[] args) {
            int a[]={ 1, 3, 4, 7, 9, 0 };
            int b[]={ 21, 23, 25, 27, 29 };
            int[] res=swapPrintArray(a,b);
            for(int i=0;i<res.length;++i){
                System.out.print(res[i]+" ");
            }
        }
        private static int[] swapPrintArray(int[] a,int[] b){
            int asize=a.length;
            int bsize=b.length;
            if(a==null&&b==null){
                return a;
            }
            if(asize==0||a==null){
                return b;
            }
            if(bsize==0||b==null){
                return a;
            }
            int[] res=new int[asize+bsize];
            int i=0;
            int j=0;
            int k=0;
            while(i<asize&&j<bsize){
                if(i==j){
                    res[k++]=a[i++];
                }else if(i>j){
                    res[k++]=b[j++];
                }
            }
            while(i<asize){
                res[k++]=a[i++];
            }
            while(j<bsize){
                res[k++]=b[j++];
            }
            return res;
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 #include<vector>
     3 
     4 using namespace std;
     5 
     6 vector<int> swapPrintArray(vector<int> &a, vector<int> &b)
     7 {
     8     if (a.empty()&&b.empty())
     9         return vector<int>();
    10     if (a.empty())
    11         return b;
    12     if (b.empty())
    13         return a;
    14     vector<int> res(a.size() + b.size());
    15     int i = 0;
    16     int j = 0;
    17     int k = 0;
    18     while (i < a.size() && j < b.size())
    19     {
    20         if (i == j)
    21             res[k++] = a[i++];
    22         else if (i > j)
    23             res[k++] = b[j++];
    24     }
    25     while (i < a.size())
    26         res[k++] = a[i++];
    27     while (j < b.size())
    28         res[k++] = b[j++];
    29     return res;
    30 }
    31 
    32 int main()
    33 {
    34     vector<int> tt = { 1, 3, 4, 7, 9, 0 };
    35     vector<int> rrr = { 21, 23, 25, 27, 29 };
    36     vector<int> res = swapPrintArray(tt, rrr);
    37     for (int i = 0; i < res.size(); ++i)
    38         cout << res[i] << " ";
    39     cout << endl;
    40 
    41     return 0;
    42 }
    View Code

    30、输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S。
    如果有多对数字的和等于S,输出两个数的乘积最小的。

    Java实现:

    package com.mian.algorithm;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class TwoSum {
        public static void main(String[] args){
            TwoSum twoSum=new TwoSum();
            int[] arr={ 3, 5, 8, 9, 12, 16, 20, 23, 29, 30, 35 };
            int target=38;
            //方法一
            List<List<Integer>> res=twoSum.twoSumMap(arr,target);
            for(int i=0;i<res.size();++i){
                for(int j=0;j<res.get(i).size();++j){
                    System.out.print(res.get(i).get(j)+" ");
                }
                System.out.println();
            }
            //方法二
            twoSum.twoSum(arr,target);
            //方法三
            twoSum.twoSumFor(arr,target);
        }
        private List<List<Integer>> twoSumMap(int[] arr,int target){
            List<List<Integer>> res=new ArrayList<>();
            int size=arr.length;
            if(size==0||arr==null){
                return res;
            }
            Map<Integer,Integer> map=new HashMap<>();
            List<Integer> tmp=null;
            for(int i=0;i<size;++i){
                if(map.containsKey(target-arr[i])){
                    tmp=new ArrayList<>();
                    tmp.add(arr[i]);
                    tmp.add((target-arr[i]));
                    res.add(tmp);
                }
                map.put(arr[i],arr[i]);
            }
            return res;
        }
        private void twoSum(int[] arr,int target){
            int size=arr.length;
            if(size==0||arr==null){
                return;
            }
            int i=0;
            int j=size-1;
            while(i<j){
                if(arr[i]+arr[j]==target){
                    System.out.println(arr[i]+" "+arr[j]);
                    ++i;
                    --j;
                }else if(arr[i]+arr[j]>target){
                    --j;
                }else{
                    ++i;
                }
            }
        }
        private void twoSumFor(int[] arr,int target){
            int size=arr.length;
            if(size==0||arr==null){
                return;
            }
            for(int i=0;i<size;++i){
                for(int j=i;j<size;++j){
                    if(arr[j]==(target-arr[i])){
                        System.out.println(arr[i]+" "+arr[j]);
                    }
                }
            }
        }
    }
    View Code

    C++实现:

     1 #include<iostream>
     2 #include<vector>
     3 #include<unordered_map>
     4 
     5 using namespace std;
     6 
     7 //方法一
     8 vector<vector<int>> twoSumMap(vector<int> &arr, int target)
     9 {
    10     vector<vector<int>> res;
    11     int size = arr.size();
    12     if (arr.empty() || size == 0)
    13         return res;
    14     unordered_map<int, int> m;
    15     for (int i = 0; i < size; ++i)
    16     {
    17         auto it = m.find(target - arr[i]);
    18         if (it != m.end())
    19         {
    20             vector<int> tmp;
    21             tmp.push_back(arr[i]);
    22             tmp.push_back(target - arr[i]);
    23             res.push_back(tmp);
    24             tmp.clear();
    25         }
    26         m[arr[i]] = arr[i];
    27     }
    28     return res;
    29 }
    30 
    31 //方法二
    32 void twoSum(vector<int> &arr, int target)
    33 {
    34     int size = arr.size();
    35     if (arr.empty() || size == 0)
    36         return;
    37     int i = 0;
    38     int j = size - 1;
    39     while (i < j)
    40     {
    41         if (arr[i] + arr[j] == target)
    42         {
    43             cout << arr[i] << " " << arr[j] << endl;
    44             ++i;
    45             --j;
    46         }
    47         else if (arr[i] + arr[j] > target)
    48             --j;
    49         else
    50             ++i;
    51     }
    52 }
    53 //方法三
    54 void twoSum2(vector<int> &arr, int target)
    55 {
    56     int size = arr.size();
    57     if (arr.empty() || size == 0)
    58         return;
    59     for (int i = 0; i < size; ++i)
    60         for (int j = i; j < size; ++j)
    61             if (arr[j] == target - arr[i])
    62                 cout << arr[i] << " " << arr[j] << endl;
    63 }
    64 
    65 int main()
    66 {
    67     vector<int> tet = { 3, 5, 8, 9, 12, 16, 20, 23, 29, 30, 35 };
    68     vector<vector<int>> vr = twoSumMap(tet, 38);
    69     for (int i = 0; i < vr.size(); ++i)
    70     {
    71         for (int j = 0; j < vr[i].size(); ++j)
    72             cout << vr[i][j] << " ";
    73         cout << endl;
    74     }
    75 
    76     twoSum(tet, 38);
    77     twoSum2(tet, 38);
    78 }
    View Code
  • 相关阅读:
    查找一 线性表的查找
    排序八 基数排序
    Numpy数组的保存与读取方法
    编写你的第一个django应用程序3
    查看当前目录的文件
    requests不加代理
    .idea文件夹是干嘛的
    python获取当前的时间
    redis命令
    windows下python安装face_recognition模块
  • 原文地址:https://www.cnblogs.com/xidian2014/p/8525946.html
Copyright © 2011-2022 走看看