數(shù)組與字符串相關(guān)的算法

最近在看 《程序員面試金典》,感覺書中的一些算法非常的精妙布卡,所以本人對書中的每一個題目都著手實現(xiàn)了一遍,為了以后能夠方便的重溫這個知識惊来,也為了能夠?qū)⑦@個算法分享給 沒看過這本書的小伙伴攀痊,于是本人決定將這些題目和算法寫下來桐腌,當(dāng)然我也只是寫下題目和解法,不會對解法進(jìn)行分析苟径,想看具體分析可以買一本紙質(zhì)書看一下案站,非常不錯的一本書。

1.1 實現(xiàn)一個算法涩笤,確定一個字符串的所有字符是否全都不同蛾坯。假設(shè)不允許使用額外的數(shù)據(jù)結(jié)構(gòu)匈睁,又該如何處理寸潦?

public class UniqueCharCheck {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        String data = input.nextLine();

        boolean result = isUniqueChar(data);
        System.out.println(result);
        input.close();
    }

    private static boolean isUniqueChar(String data) {
        if (data.length() > 256) // 假設(shè)字符是 ASCII 字符
            return false;
        boolean[] check = new boolean[256];

        for (int i = 0; i < data.length(); i++) {
            int v = data.charAt(i);
            if (check[v])
                return false;
            check[v] = true;
        }
        return true;
    }

}

1.2 用 C/C++ 實現(xiàn) void reverse(char* str) 函數(shù)避凝,即翻轉(zhuǎn)一個 null 結(jié)尾的字符串。

#include<iostream>
using namespace std;

void reverse(char *str);
int main()
{
    char s[100];
    cin>>s;
    
    reverse(s);

    cout<<s<<endl;
    return 0;
}

void reverse(char *str)
{
    char *end = str;
    char *start = str;
    while(*end) 
        ++end;
    --end;
    while(start < end)
    {
        char temp = *start;
        *start++ = *end;
        *end-- = temp;
    }

    return;
}

1.3 給定兩個字符串恩沽,請編寫程序誊稚,確定其中一個字符串的字符重新排列后,能否變成另一個字符串罗心。

public class EqualCheck {
    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);
        String v = input.nextLine();
        String t = input.nextLine();
        input.close();
        System.out.println(permutation(v, t));
    }
        
    public static String sort(String s) {
        char[] array = s.toCharArray();
        java.util.Arrays.sort(array);
        return new String(array);
    }

    // 這是第一種方法
    public static boolean compare(String s, String t) {
        return sort(s).equals(sort(t));
    }
    
    
    // 這是第二種方法
    public static boolean permutation(String s, String t) {
        if (s.length() != t.length())
            return false;

        int check[] = new int[256];
        for (int i = 0; i < s.length(); i++) {
            int v = s.charAt(i);
            check[v]++;
        }

        for (int i = 0; i < t.length(); i++) {
            int v = t.charAt(i);
            if (--check[v] < 0)
                return false;
        }
        return true;
    }
}

1.4 編寫一個方法里伯,將字符串中的空格全部替換成 “ %20”,假定字符串尾部有足夠的空間存放新增字符渤闷,并且知道字符串的 “ 真實” 長度疾瓮。(注: 用 Java 實現(xiàn)的話,請用字符數(shù)組實現(xiàn)飒箭,以便直接在數(shù)組上進(jìn)行操作)狼电。

public class ReplaceSpace {
    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);
        String s = input.nextLine();
        s = replace(s);

        System.out.println(s);
        input.close();
    }

    public static String replace(String s) {
        int count = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == ' ')
                count++;
        }

        int newLength = s.length() + count * 2;
        char array[] = new char[newLength];

        for (int i = s.length() - 1; i >= 0; i--) {
            char t = s.charAt(i);
            if (t == ' ') {
                array[newLength - 1] = '0';
                array[newLength - 2] = '2';
                array[newLength - 3] = '%';
                newLength -= 3;
            } else {
                array[newLength - 1] = t;
                newLength -= 1;
            }
        }

        return new String(array);

    }

}

1.5 利用字符重復(fù)出現(xiàn)的次數(shù),編寫一個方法弦蹂,實現(xiàn)基本的字符串壓縮功能肩碟。比如,字符串 "aabcccccaaa" 會變?yōu)?“ a2b1c5a3”凸椿,若“壓縮”后的字符串沒有變短削祈,則返回原先的字符串。

public class ZipStringData {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);
        String s = input.nextLine();

        s = zip(s);

        System.out.println(s);
        input.close();
    }

    private static String zip(String s) {
        int size = check(s); // 壓縮后的字符串長度
        if (size >= s.length()) // 如果壓縮后的字符串長度大于等于原來的長度,直接返回原字符串
            return s;

        StringBuilder builder = new StringBuilder(); // 使用 StringBuilder 進(jìn)行連接髓抑,減小時間開銷
        char last = s.charAt(0);
        int count = 1;
        for (int i = 1; i < s.length(); i++) {
            if (last == s.charAt(i))
                count++;
            else {
                builder.append(last + "" + count);
                last = s.charAt(i);
                count = 1;
            }
        }

        builder.append(last + "" + count);

        return builder.toString();
    }

    // 用于計算壓縮后的字符串長度
    private static int check(String s) {
        int size = 0;
        char last = s.charAt(0);
        int count = 1;

        for (int i = 1; i < s.length(); i++) {
            if (s.charAt(i) == last) {
                count++;
            } else {
                size += 1 + String.valueOf(count).length();
                last = s.charAt(i);
                count = 1;
            }
        }
        size += 1 + String.valueOf(count).length();
        return size;
    }

}

1.6 給定一副由 N×N 矩陣表示的圖像咙崎,其中每個像素的大小為 4 字節(jié),編寫一個方法启昧,將圖形旋轉(zhuǎn) 90 度叙凡。不占用額外內(nèi)存空間能否做到?

public class MatrixRotate {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);
        int[][] matrix;

        int n = input.nextInt();
        matrix = new int[n][n];

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                matrix[i][j] = input.nextInt();
            }
        }
        show(matrix);

        rotate(matrix, n);

        show(matrix);

        input.close();

    }

    public static void show(int[][] matrix) {
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                System.out.print(matrix[i][j] + " ");
            }
            System.out.println();
        }
    }

    public static void rotate(int[][] matrix, int n) {

        for (int layer = 0; layer < n / 2; layer++) { // 因為每次旋轉(zhuǎn)會旋轉(zhuǎn)兩行兩列密末,所以上限為 n/2

            int first = layer;
            int last = n - layer - 1;

            for (int i = first; i < last; i++) {
                
                int offset = i - first;

                int top = matrix[first][i]; //保存上邊元素值

                matrix[first][i] = matrix[last - offset][first];  // 左邊覆蓋上邊
                matrix[last - offset][first] = matrix[last][last - offset]; //下邊覆蓋左邊
                matrix[last][last - offset] = matrix[offset][last]; // 右邊覆蓋下邊
                matrix[offset][last] = top; // 將保存的值覆蓋到下邊
            }

        }
    }

}

1.7 編寫一個算法,若 M × N 矩陣中的某個元素為 0 跛璧,則將其所在的行與列置為 0严里。

public class ResetMatrix {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int m = input.nextInt();
        int n = input.nextInt();
        int[][] matrix = new int[m][n];
        boolean[] row = new boolean[matrix.length];
        boolean[] column = new boolean[(matrix[0].length)];

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                matrix[i][j] = input.nextInt();
                if (matrix[i][j] == 0) {
                    row[i] = true;
                    column[j] = true;
                }
            }
        }
        show(matrix);

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (row[i] || column[j]) {
                    matrix[i][j] = 0;
                }
            }
        }
        
        show(matrix);
    }

    public static void show(int[][] matrix) {
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                System.out.print(matrix[i][j] + " ");
            }
            System.out.println();
        }
    }
}

1.8 假定有一個方法 isSubstring , 可檢查一個單詞是否為其他字符串的子串追城。給定兩個兩個字符串 s1 和 s2刹碾,請編寫代碼檢查 s2 是否為 s1 旋轉(zhuǎn)而成,要求只能調(diào)用 一次 isSubstring座柱。(比如迷帜,waterbottle 是 erbottlewat 旋轉(zhuǎn)后的字符串)。

public boolean isRotation(String s1,String s2){
        int length = s1.length();
        
        if(length == s2.length() && length > 0){
            String s1s1 = s1+s1; // 若s2 是由 s1 旋轉(zhuǎn)而成色洞,那么 s2 必然是 s1s1 的子串
            return isSubstring(s1s1,s2);
        }
        return false;
    }

再次聲明戏锹,以上題目和算法均來自 《程序員面試金典》。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末火诸,一起剝皮案震驚了整個濱河市锦针,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌置蜀,老刑警劉巖奈搜,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異盯荤,居然都是意外死亡馋吗,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門秋秤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宏粤,“玉大人,你說我怎么就攤上這事航缀∩碳埽” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵芥玉,是天一觀的道長蛇摸。 經(jīng)常有香客問我,道長灿巧,這世上最難降的妖魔是什么赶袄? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任揽涮,我火速辦了婚禮,結(jié)果婚禮上饿肺,老公的妹妹穿的比我還像新娘蒋困。我一直安慰自己,他們只是感情好敬辣,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布雪标。 她就那樣靜靜地躺著,像睡著了一般溉跃。 火紅的嫁衣襯著肌膚如雪村刨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天撰茎,我揣著相機與錄音嵌牺,去河邊找鬼。 笑死龄糊,一個胖子當(dāng)著我的面吹牛逆粹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播炫惩,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼僻弹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了诡必?” 一聲冷哼從身側(cè)響起奢方,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎爸舒,沒想到半個月后蟋字,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡扭勉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年鹊奖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涂炎。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡忠聚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出唱捣,到底是詐尸還是另有隱情两蟀,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布震缭,位于F島的核電站赂毯,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜党涕,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一烦感、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧膛堤,春花似錦手趣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至燕耿,卻和暖如春怯晕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背缸棵。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谭期,地道東北人堵第。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像隧出,于是被迫代替她去往敵國和親踏志。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容