面試算法題

1    

    /*
    * 
    *   [1,2,3,-2,-4,5,3,-2,4,1,-5,3]數組排序
    *  輸出結果[1,2,3,5,3,4,1,3,-2,-4,-2,-5]
    * 要求:
    *1.正數在左,負數在右,
    *2.相對順序不變,
    *3.空間複雜度O(1)
    *
    * 兩種思路第二種好: 仔細看題,反方向考慮,既然小於0 的要放到最右邊,所以只需要把大於0的往左邊移動即可(往左冒泡)
    *
    */


    /* 解題思路1:
    * 1 首先找到小於0的
    * 2 從小與0的位置開始往後找大於0 的第一個數
    * 3 再使用冒泡,將大於0替換掉最前面那個小於0 的(判斷條件: 小於0前面的數字是大於0 即可)
    */

public static void function1(int[] data){
        int temp=0;
        int index=0;
        for(int i=0;i<data.length;i++){
            if(data[i]<0){
                for(int j=i+1;j<data.length;j++){
                    if(data[j]>0){
                        //說明是第一次
                        if((j-1)==i){
                            temp=data[i];
                            data[i]=data[j];
                            data[j]=temp;
                            break;
                        }else{
                            while(index<(j-i)){
                                //交換
                                temp=data[j-index];
                                data[j-index]=data[j-1-index];
                                data[j-1-index]=temp;
                                ++index;
                            }
                        }
                        if(index>0) index=0;break;
                    }
                }
            }

        }
        for(int i=0;i<data.length;i++){
            System.out.println(data[i]);
        }
    }

 兩種思路二: 反方向考慮,既然小於0 的要放到最右邊,所以只需要把大於0的往左邊移動即可(往左冒泡)

/*
    * 1 當data[i]大於0時進行向上冒泡
    * 2 條件: 從第二個元素開始,前面一個元素小於0
    * 3 冒泡交換值,交換後將 下標置0
    *  時間複雜度低
    **/
    public static void f2(int[] data) {
        int temp = 0;
        int index = 0;
        int loop=0;
        for (int i = 0; i < data.length; i++) {
            //如果當前data[i]大於0並且前面data[i-1]也是大於0 則不進行循環
            if (data[i] > 0 && i != 0 && data[i - 1] < 0) {
                //將大於0的網上冒泡,直到大於0的出現
               while (i-1-index>=0&&data[i-1-index]<0) {
                    //交換
                    temp = data[i - index];
                    data[i - index] = data[i - 1 - index];
                    data[i - 1 - index] = temp;
                    ++index;
                }
                 index=0;

        }
    }

//對方法2code review

public static void f2Review(int[] data) {
        int temp = 0;
        int currentIndex=0;
        for (int i = 0; i < data.length; i++) {
            //如果當前data[i]大於0並且前面data[i-1]也是大於0 則不進行循環
            if (data[i] > 0 && i != 0 && data[i - 1] < 0) {
                //將大於0的網上冒泡,直到大於0的出現
                currentIndex=i-1;

               while(currentIndex>=0&&data[currentIndex]<0){
                    //交換
                    temp = data[currentIndex+1];
                    data[currentIndex+1] = data[currentIndex];
                    data[currentIndex] = temp;
                    loop--;
                }

            }
        }
    }

掌握算法,以及思路,很多時候爲了解決問題而陷阱到題目中去了,這樣就會想方法1一樣多寫很多無用的代碼,並且將題目想的複雜化了增加了出錯的可能性,也降低的代碼的可讀性,所以很多時候我們做事不妨跳出當前的怪圈去思考問題,反方向,或者以另外一種視覺去看待問題,反而能有更好的解決方案

後續繼續更新

2  考察的是 冒泡排序以及對String類的應用熟悉度,涉及到了字符串的比較

 /*
    *  給定一個非0數組組成一個最大的數字:
    *  [12,324,67,2]  ----->   67324212
    *  字符排序
    */
    public  static void getBigNum(String[] data){
        StringBuilder stringBuilder = new StringBuilder();
        List<String> list = Arrays.asList(data);
        //冒泡算法
        String temp;
        for(int i=0;i<data.length-1;i++){
            for(int j=i+1;j<data.length;j++){
                if(data[i].compareTo(data[j])>0){
                    temp=data[i];
                    data[i]=data[j];
                    data[j]=temp;
                }
            }
        }
        for(int i=data.length-1;i>0;i--){
           stringBuilder.append(data[i]);
        }

        System.out.println(stringBuilder.toString());
    }

3 鏈表反轉

package com.算法;


public class SingleList {
     class Element {
        public  Element(Object value,Element next){
            this.value=value;
            this.next=next;
        }

         public  Element(){
         }

        public Object value = null;
        private Element next = null;
    }



    private Element head = null; //頭結點

    /**
     * 初始化鏈表
     */
    void init() {
        head = new Element();
        head.value = null;
        head.next = null;
    }

    /**
     * 插入鏈表
     */
    void insertLinkList(Object o) {
        if (head==null) {
            //說明尚未初始化
            init();
        }
       Element element = head;
        while (element.next !=null) {
            //如果不是頭
            element = element.next;
        }

        if(head.value==null){
            head.value=o;
            return;
        }
        Element addElement = new Element();
        addElement.value = o;
        //註釋掉循環鏈表
        //addElement.next = head;
        element.next = addElement;
    }


    public  static void main(String[] args){
        SingleList circleLinkList=new SingleList();
        circleLinkList.insertLinkList("1");
        circleLinkList.insertLinkList("2");
        circleLinkList.insertLinkList("3");
        circleLinkList.insertLinkList("4");

        new SingleList().revser(circleLinkList);
    }

    public   void revser( SingleList circleLinkList){
        Element head = circleLinkList.head;
        Element currentElement=head.next;
        //用於存放反轉後的上一個節點
        Element next=head;
        Element temp=null;
        while(currentElement!=null){
            temp=currentElement.next;
            //存放上一個
            currentElement.next=new Element(next.value,(currentElement==head.next)?null:next.next);
            //存放當前節點
            next=currentElement;
            //反轉前的上一個節點
            currentElement=temp;
        }
        while (next!=null){
            System.out.println(next.value);
            next=next.next;
        }




    }
}

總結: 重點在於將當前節點的上一個節點作爲當前節點的下一個節點,並且不能影響後面的鏈表反轉

4 字符串反轉: 首尾相互替換,如果爲奇數中間的就不需要動

public static void main(String[] args){
    /*
    *  利用最少的空間將字符串反轉
    */
    String data="0123456789";
    //計算出需要互換的次數
    int num=data.length()>>1;
    char[] chars = data.toCharArray();
    char before;
    char after;
    for(int i=0;i<num;i++){
         before=chars[i];
         after=chars[data.length()-1-i];
        chars[data.length()-1-i]=before;
        chars[i]=after;
    }
    System.out.println(new String(chars));
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章