大公司面试经典数据结构与算法题C#/Java解答

几个大公司(IBM、MicroSoft and so on)面试经典数据结构与算法题C#解答

1.链表反转

我想到了两种比较简单的方法

第一种是需要开一个新的链表,将原链表的元素从后到前的插入到新链表中(也就是原链表第一个元素被插入成新链表的最后一个元素)。

第二种是不需要开新的链表,而是逐步反转原链表中元素的指向,例如:

原链表是 1->2->3->4->null  被  逐步修改为 ①2->1->null、3->4->null ②3->2->1->null、4->null ③4->3->2->1->null

最后再将head指向4。

  1 namespace 链表反转
  2 {
  3     class Node 
  4     {
  5         public int Num { get; set; }
  6         public Node Next { get; set; }
  7     }
  8     class Program
  9     {
 10         static void Main(string[] args)
 11         {
 12             NodeList list = new NodeList();
 13             list.Add(1);
 14             list.Add(2);
 15             list.Add(3);
 16             list.Add(4);
 17             list.Add(5);
 18             list.Reverse1();
 19             list.Print();
 20 
 21             NodeList list1 = list.Reverse();
 22             list1.Print();
 23 
 24             Console.ReadKey();
 25         }
 26     }
 27 
 28     class NodeList
 29     {
 30         public Node Head { get; set; }
 31         public void Add(int num)
 32         {
 33             if (Head == null)
 34             {
 35                 Head = new Node();
 36                 Head.Next = new Node() { Num = num };
 37             }
 38             else
 39             {
 40                 Node tn = Head;
 41                 while (tn.Next != null)
 42                 {
 43                     tn = tn.Next;
 44                 }
 45                 tn.Next = new Node() { Num = num };
 46             }
 47         }
 48 
 49         public void Print()
 50         {
 51             Node tn = Head;
 52             while(tn.Next!=null)
 53             {
 54                 tn = tn.Next;
 55                 Console.WriteLine(tn.Num);
 56             }    
 57         }
 58 
 59         //需要开新链表的反转
 60         public NodeList Reverse()
 61         {
 62             NodeList list = new NodeList();
 63             Node tn = Head;
 64             Node newTn = null;
 65             while (tn.Next != null)
 66             {
 67                 tn = tn.Next;
 68                 if (newTn == null)
 69                 {
 70                     newTn = new Node() { Num = tn.Num };
 71                 }
 72                 else
 73                 {
 74                     newTn = new Node() { Num = tn.Num,Next=newTn };
 75                 }
 76             }
 77             list.Head = new Node();
 78             list.Head.Next = newTn;
 79             return list;
 80         }
 81 
 82         //不需要开新链表的反转
 83         public void Reverse1()
 84         {
 85             Node n1 = Head.Next;
 86             Node n2 = Head.Next.Next;
 87             //第一个节点也就是反转后的最后一个节点,Next要指向null
 88             Node first = Head.Next;
 89             first.Next = null;
 90             //如果链表为空或者链表只有一个元素那就无需调整
 91             if (n2 == null || n1 ==null)
 92             {
 93                 return;
 94             }     
 95             //先用Head指向n2的下一个元素,再将n2的Next指向n1,最后将n1和n2向右移动
 96             while (n2.Next != null)
 97             {
 98                 Head.Next = n2.Next;
 99                 n2.Next = n1;
100                 n1 = n2;
101                 n2 = Head.Next;
102             }
103             //最后要将头结点指向链表反转前的最后一个元素
104             Head.Next = n2;
105             //因为判断条件只调整到最后一个元素的前一个元素,所以要调整最后一个元素的Next指向
106             n2.Next = n1;           
107         }
108     }

2.字符串查找第一个不重复的字母

基本原理:第一遍遍历字符串时,用hash表存储每个字符出现的次数,第二遍遍历字符串时,筛选出第一个hash中对应保存的出现次数为1的字符。

 1 namespace 字符串查找第一个不重复的字母
 2 {
 3     class Program
 4     {
 5         static Hashtable hash = new Hashtable();   
 6         static void Main(string[] args)
 7         {
 8             string s = "asfgasjfoiwoeqkwzxc";
 9             Count(s);
10             Console.WriteLine(Search(s));
11             Console.ReadKey();
12         }
13 
14         static void Count(string s)
15         {
16             for (int i = 0; i < s.Length; i++)
17             {
18                 if (hash.Contains(s[i]))
19                 {
20                     hash[s[i]] = (int)hash[s[i]]+1;
21                 }
22                 else
23                 {
24                     hash[s[i]] = 1;
25                 }
26             }
27         }
28 
29         static char Search(string s)
30         {
31             for (int i = 0; i < s.Length; i++)
32             {
33                 if ((int)hash[s[i]] == 1)
34                 {
35                     return s[i];
36                 }
37             }
38             return '#';
39         }
40     }
41 }

3.有一个已经排序的数组(升序),数组中可能有正数、负数或0,求数组中元素的绝对值最小的数,要求,不能用顺序比较的方法(复杂度需要小于O(n)),可以使用任何语言实现

基本原理:找到正负数分界点0,如果存在就是0,不存在就比较它左右两个数的绝对值。

(PS:为了方便我写到一个JUnit方法中)

public class testAlgorithm {
    @Test
    public void Fun(){
        int[] a = {-8,-7,-5,1,3,5};
        
        int middle = (a.length-1)/2;
        int result = middle;
        
        if (a[middle]==0){
            System.out.println("The smallest number is "+a[middle]);
            return;
        }
        //find the demarcation point
        else{
            if(a[result]>0){
                while(a[result]>0){
                    result = result - 1;        
                }
                if(Math.abs(a[result])>a[result+1]){
                    System.out.println("The smallest number is "+a[result+1]);
                    return;
                }
                else{
                    System.out.println("The smallest number is "+a[result]);
                    return;
                }
            }
            else{
                while(a[result]<0){
                    result = result + 1;
                }
                if(a[result]>Math.abs(a[result+1])){
                    System.out.println("The smallest number is "+a[result+1]);
                    return;
                }
                else{
                    System.out.println("The smallest number is "+a[result]);
                    return;
                }
            }
                        
        }
        
    }
    
}

 

posted @ 2015-05-03 20:43  Sunnier  阅读(5950)  评论(0编辑  收藏  举报