微软算法100题88 将字符串中的字符'*'移到串的前部分

函数将字符串中的字符‘*‘移到串的前部分,前面的非‘*‘字符后移,但不能改变非‘*‘字符的先后顺序,函数返回串中字符‘*‘的数量。如原始串为:ab**cd**e*12,处理后为*****abcde12,函数并返回值为5。(要求使用尽量少的时间和辅助空间)

思路:类似于快速排序,用两个指针分别指向字符数组的左右边界,寻找左边第一个不为*的字符,寻找右边第一个*,然后交换字符,然后继续寻找和交换的过程,直到两个指针相交, 时间复杂度o(n), 空间复杂度o(1)

第一个写的程序有问题,没有考虑到保持原有顺序的要求。。。

 1 package com.rui.microsoft;
 2
 3 //字符串中的字符‘*‘移到串的前部分,前面的非‘*‘字符后移
 4 public class Test88_MoveStar {
 5
 6     public static void main(String[] args) {
 7         char[] a = "*ab**1*23*".toCharArray();
 8         Test88_MoveStar app = new Test88_MoveStar();
 9         app.move(a);
10         for(char t: a){
11             System.out.print(t);
12         }
13     }
14
15     void move(char[] a){
16         int left = 0;
17         int right = a.length - 1;
18         while(true){
19             while(a[left] == ‘*‘ && left < a.length-1){
20                 left++;
21             }
22
23             while(a[right] != ‘*‘ && right > 0){
24                 right--;
25             }
26
27             if(left >= right) break;
28             swap(a,left,right);
29         }
30     }
31
32     void swap(char[] a, int i, int j){
33         char tmp = a[i];
34         a[i] = a[j];
35         a[j] = tmp;
36     }
37 }

再写一个 可以保持原有非*字符的顺序

 1 package com.rui.microsoft;
 2
 3 //字符串中的字符‘*‘移到串的前部分,前面的非‘*‘字符后移
 4 public class Test88_MoveStar {
 5
 6     public static void main(String[] args) {
 7         char[] a = "*ab**1*23*".toCharArray();
 8         Test88_MoveStar app = new Test88_MoveStar();
 9         int total = app.moveAndKeepSeq(a);
10         System.out.println("total: " + total);
11         for(char t: a){
12             System.out.print(t);
13         }
14     }
15
16     int moveAndKeepSeq(char[] a){
17         int i = a.length -1;
18         int j = a.length -1;
19         int count = 0;
20         while(i>=0){
21             if(a[i] == ‘*‘){
22                 i--;
23                 count++;
24             }else{
25                 swap(a,i--,j--);
26             }
27         }
28         return count;
29     }
30
31     void swap(char[] a, int i, int j){
32         char tmp = a[i];
33         a[i] = a[j];
34         a[j] = tmp;
35     }
36 }

微软算法100题88 将字符串中的字符'*'移到串的前部分

时间: 2024-08-05 07:08:10

微软算法100题88 将字符串中的字符'*'移到串的前部分的相关文章

微软算法100题17 字符串中找到第一个只出现一次的字符

第17 题:题目:在一个字符串中找到第一个只出现一次的字符.如输入abaccdeff,则输出b 思路:要找出只出现一次的字符,很明显需要统计所有字符出现的次数,然后找出次数为一的那一个,统计次数最先想到的是hashTable,但此题有更好的办法,因为每个char其实对应一个唯一的ASCII值,所以可以构造一个包含所有字符ASCII值的int数组,来映射字符与出现次数的关系,同时一个char是8个字节,总共有256个可能,所以该数组的大小应为256 1 package com.rui.micros

微软面试100题系列:字符串匹配算法,查找包含字符集的子串

觉得这题挺有意思,看了别的博客,找到了一种目前看来还不错的算法,为强化理解,就写了下来. 题目意思: 实现一个挺高级的字符匹配算法: 给一串字符串,要求找到符合要求的字符串,例如对于目的串:123,那么给定字符串中诸如1******3*****2,12******3这些形式的子串都要找出来,即子串中含有目的串的所有字符,输出所有符合条件的字符串,并求出最短子串 .类似于和谐系统. 例如:假如目的串为:"423",输入长字符串为:"4fsdfk2jfl3fd2jfksd3j4d

微软算法100题25 查找连续最长的数字串

第25 题:写一个函数,它的原形是int continumax(char *outputstr,char *intputstr)功能:在字符串中找出连续最长的数字串,并把这个串的长度返回,并把这个最长数字串付给其中一个函数参数outputstr 所指内存.例如:"abcd12345ed125ss123456789"的首地址传给intputstr 后,函数将返回9,outputstr 所指的值为123456789 思路:两个指针,一个保存当前最长长度的变量max,然后移动指针,直到到字符

微软算法100题20 字符串转整数 atoi

第20 题:题目:输入一个表示整数的字符串,把该字符串转换成整数并输出.例如输入字符串"345",则输出整数345 思路:atoi 主要考虑的是对输入的校验和边界处理,以及处理正负符号等 1 package com.rui.microsoft; 2 3 public class Test20_String2Int { 4 5 public static void main(String[] args) { 6 int sum = Test20_String2Int.convert(&q

微软算法100题69 求旋转数组中的最小元素

69.求旋转数组中的最小元素.题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个排好序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1 思路: 1. 可以从左到右扫描整个数组,找出最小的那个,时间复杂度是o(n) 2. 也可以利用旋转数组本身的特性,即部分有序,然后借助二分查找的方法来解决,先找中间点mid = left + (right - left)/2, 如果a[le

微软算法100题04 二叉树中查找和为某值的所有路径

4.在二元树中找出和为某一值的所有路径题目:输入一个整数和一棵二元树.从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径.打印出和与输入整数相等的所有路径.例如输入整数22 和如下二元树10/ \5 12/ \4 7则打印出两条路径:10, 12 和10, 5, 7 思路: 递归 为了记录路径 需要采用一个辅助数据结构记录正确路径上的节点 这里采用list 1. 从根节点开始 将根节点放入List 将总额sum减去根节点的值 如果等于零 说明找到正确路径上的节点 则打印list 2

微软算法100题01 二叉搜索树转为双向链表

提高编程能力的最佳途径就是多写代码, 就让我们从现在开始吧! 1. 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向.       10      /    |   6     14 /   |     /  |4   8   12  16 转换成双向链表4=6=8=10=12=14=16. 二叉查找树的特点:任意节点的左子树都要小于当前节点:右子树都要大于当前节点.特点:查询某个值,需要的时间复杂度为O(lgN) 网上的解决方案大部分都是C

微软算法100题68 用数组排成最小的数

68.把数组排成最小的数.题目:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个.例如输入数组{32, 321},则输出这两个能排成的最小数字32132.请给出解决问题的算法,并证明该算法 1 package com.rui.microsoft; 2 3 import java.util.Arrays; 4 import java.util.Comparator; 5 6 public class Test68_Minimum { 7 8 public static

微软算法100题03 求子数组的最大和

3.求子数组的最大和题目:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值.要求时间复杂度为O(n).例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,因此输出为该子数组的和18 思路:使用辅助变量max 记录子数组的最大和,从数组头开始遍历,如果数组元素与之前的总和的sum是负数,则重置sum结果为零,否则将得到的sum值与max比较 如果小于ma