2015年8月6日 星期四

LEET code--Single Number

Single Number


Given an array of integers, every element appears twice except for one. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

最快想試用兩個for 暴力算

但是要線性又不要求多餘空間
就很難阿

看到有人用XOR  真是天才
因為兩個依樣數字就會剛好抵銷


numsSize>1 是因為 用了nums[0]  要把0給跳過
------------
int singleNumber(int* nums, int numsSize) {
    while(numsSize>1){
        nums[0]^=nums[--numsSize];
    }
    return nums[0];
}

2015年7月31日 星期五

LEET code--Longest Common Prefix

Longest Common Prefix


Write a function to find the longest common prefix string amongst an array of strings.

找出一堆字串中
起始一起出現的值

s1: abaccc
s2: abccc
s3: abrrr

LCP=ab   三個都從ab開始


因為會有空字串  要注意
用char *ans 最好都要malloc 
strdup 會把你傳進去的字串 用malloc 一個空間把string複製過去回傳指標回來
感覺很好用!!!


char* longestCommonPrefix(char** strs, int strsSize) {
    char *ans="";
   
    int strindex=0,index=0;
    if(strsSize ==0)return ans;
    if(strsSize ==1)return strs[0];
    if(strs[0][index]=='\0')return ans;
   
    //ans[index]=strs[0][index];
    while(1){
        for( int i = 1 ; i < strsSize ; i++ )
      {
            if( strs[0][index] != strs[i][index] || strs[0][index]=='\0'){
               
                if(index>=1){
                    ans =strdup(strs[0]);
                    ans[index]='\0';
                }
                return ans;
            }
        }
        index++;
       // ans[index]=strs[0][index];
    }
   
}

C--double pointer cahr**

Dereferencing" a pointer means accessing the value the pointer points to. Assume the following declarations:
int a = 10;
int *p = &a;
Here's a hypothetical memory map of the two variables:
Item      Address      0x00  0x01  0x02  0x03
----      -------      ----  ----  ----  ----
   a      0x80001000   0x00  0x00  0x00  0x0A
   p      0x80001004   0x80  0x00  0x10  0x00
a contains the integer value 10. p contains the address of a (0x80001000). If we want to access the contents of a through p, we dereference p with the indirection operator *. Thus, the expression *p is equivalent to the expression a. If we wrote
 *p = 16;
that's the same as writing
  a = 16;
Here's a short snippet of code showing how to use an object of type char ** to create an array of strings:
#include 
#define N      20  // For this example, we will allocate 20 strings
#define LENGTH 10  // of 10 characters each (not counting 0 terminator)
...
char **arr = malloc(sizeof *arr * N); 
if (arr)
{
  size_t i;
  for (i = 0; i < N; i++)
  {
    arr[i] = malloc(sizeof *arr[i] * (LENGTH + 1)); 
    strcpy(arr[i], "          "); 
  }
}
Going through it line by line,
char **arr = malloc(sizeof *arr * N); 
allocates a block of N elements, each large enough to store a pointer to char (sizeof *arr == sizeof (char *) since type of *arr == char *), and assigns the resulting pointer value to arr. IOW, arr points to the first pointer to char, hence the type char **. Note that if you separated the declaration and the function call, it would look like
char **arr;
...
arr = malloc(sizeof *arr * N);
We want to assign the result of malloc to arr, not to what arr points to.
if (arr)
It's possible for malloc to fail, so we want to check the result before using it. In the event malloc fails it will return a NULL pointer value.
{
  size_t i;
  for (i = 0; i < N; i++)
  {
    arr[i] = malloc(sizeof *arr[i] * (LENGTH + 1));
For each character pointer arr[i], we allocate a block of memory large enough for LENGTH+1 elements, each large enough to hold a char value (sizeof *arr[i] == sizeof (char), since type of *arr[i] == char; note that sizeof (char) is always 1) and assign the result to arr[i].
Since we allocate each string with a separate malloc call, it's unlikely that they are contiguous in memory. Here's another memory map showing a possible result of the code above:

Item         Address        0x00  0x01  0x02  0x03
----         -------        ----  ----  ----  ----
 arr         0x80001000     0xA0  0xCC  0x00  0x00  
             ...
 arr[0]      0xA0CC0000     0xA0  0xCC  0x20  0x00     
 arr[1]      0xA0CC0004     0xA0  0xCC  0x20  0x40
 arr[2]      0xA0CC0008     0xA0  0xCC  0x21  0x28
             ...
 arr[19]     0xA0CC0014     0xA0  0xCC  0x23  0x10
             ...
 arr[0][0]   0xA0CC2000     ' '   ' '   ' '   ' '
 arr[0][4]   0xA0CC2004     ' '   ' '   ' '   ' '
 arr[0][8]   0xA0CC2008     ' '   ' '   0x00  0x??
             ...
 arr[1][0]   0xA0CC2040     ' '   ' '   ' '   ' '
 arr[1][4]   0xA0CC2044     ' '   ' '   ' '   ' '
 arr[1][8]   0xA0CC2048     ' '   ' '   0x00  0x??

-------------------------------------------------



Dereferencing a pointer means accessing the value the pointer points to. For example,
char c = 'c'; // This is a primitive value. You cannot dereference it.
char* p1 = &c; // A pointer to the address of c
char** p2 = &p1; // A pointer to the address of p1
/* Now, the following is true:
*p1 == c, i.e. dereferencing p1 allows us to read from/write to c.
*p2 == p1
**p2 == *(*p2) == *p1 = c - dereferencing p2 twice is c, too */
The reason why you use a pointer to c instead of c directly is that a pointer allows you to access more than 1 value. Take this example:
char[4] str;
char c0 = 'a', c1 = 'b', c3 = 'c', c4 = '\0';
str[0] = c0; str[1] = c1; str[2] = c2; str[3] = c3;
str = "abc"; // Same as the above line
Now suppose we need the second character. We could access it with c1. But as you can see, this notation is really cumbersome. Plus, if we read the string from a file instead of writing it, we'd have to do complicated things. Instead, we just write
str[1] /* or */ *(str+1)
Note that the first element has the index 0, the second 1 - that's why we're using 1 here. A char** turns this up to eleven - we have an array of an array of chars. Suppose we have such an array, let's call it input, and need to find out the length of all the strings in it. This is how we would do it:
int lensum(char **input) {
    int res = 0;
    while (*input) { // This loops as long as the value input points to is not 0.
        char* p = *input; // Make a copy of the value input currently points to
        while (*p != '\0') { // Loop while the copy does not point to a char '\0'
            res += 1; // We found a character
            p++; // Check next character in the next iteration
        }
        input++; // Check next string in the next iteration
    }
    return res;
}             ...

LEET code--Roman to Integer

Roman to Integer


Given a roman numeral, convert it to an integer.

Input is guaranteed to be within the range from 1 to 3999.


一開始寫法

/*
I=1 V=5 X=10 L=50 C=100 D=500 M=1000
IV=4 IX=9 XL=40 XC=90 CD=400 CM=900
*/
int roman(char *s){
    if(*s=='I')return 1;
    if(*s=='V')return 5;
    if(*s=='X')return 10;
    if(*s=='L')return 50;
    if(*s=='C')return 100;
    if(*s=='D')return 500;
    if(*s=='M')return 1000;
}
int romanToInt(char* s) {
    if(*s=='\0')return 0;
    int ans=0, size=0;
    while(s[size]!='\0'){
        if( s[size+1]!='\0' ){
            if(s[size]=='I' && s[size+1]=='V' ){ans+=4;size+=2;}
            if(s[size]=='I' && s[size+1]=='X' ){ans+=9;size+=2;}
            if(s[size]=='X' && s[size+1]=='L' ){ans+=40;size+=2;}
            if(s[size]=='X' && s[size+1]=='C' ){ans+=90;size+=2;}
            if(s[size]=='C' && s[size+1]=='D' ){ans+=400;size+=2;}
            if(s[size]=='C' && s[size+1]=='M' ){ans+=900;size+=2;}
         
        }
        if(s[size]!='\0'){
            ans+=roman(s[size]);
            size++;
        }
    }
    return ans;
}


但是不會過

因為我這邊是用s[size] 是char的型態
不是char*  所以在傳到roman(char*)會壞掉
要嘛全部char*  或是全部改成char
但是這樣還是會錯 因為我沒考慮到XC會連續的情況
所以如果是XCXC
那第一次處理完XC 會直接以為是X  不會是XC
全部加else就好了

-----
/*
I=1 V=5 X=10 L=50 C=100 D=500 M=1000
IV=4 IX=9 XL=40 XC=90 CD=400 CM=900
*/
int roman(char s){
    if(s=='I')return 1;
    if(s=='V')return 5;
    if(s=='X')return 10;
    if(s=='L')return 50;
    if(s=='C')return 100;
    if(s=='D')return 500;
    if(s=='M')return 1000;
}
int romanToInt(char* s) {
    if(*s=='\0')return 0;
    int ans=0, size=0;
    while(s[size]!='\0'){
            if(s[size]=='I' && s[size+1]=='V' ){ans+=4;size+=2;}
            else if(s[size]=='I' && s[size+1]=='X' ){ans+=9;size+=2;}
            else if(s[size]=='X' && s[size+1]=='L' ){ans+=40;size+=2;}
            else if(s[size]=='X' && s[size+1]=='C' ){ans+=90;size+=2;}
            else if(s[size]=='C' && s[size+1]=='D' ){ans+=400;size+=2;}
            else if(s[size]=='C' && s[size+1]=='M' ){ans+=900;size+=2;}
            else {ans+=roman(s[size]); size++;}
    }
    return ans;
}

-----------
網路上更好的寫法
因為4跟9 都是 後面比前面大
所以檢查這個就知道是不是4或9

int romanToInt(char* s) {
    int N=strlen(s);
    int map[26]={0};
    map['I'-'A']=1;
    map['V'-'A']=5;
    map['X'-'A']=10;
    map['L'-'A']=50;
    map['C'-'A']=100;
    map['D'-'A']=500;
    map['M'-'A']=1000;
    // main loop
    int sum=0;
    for(int i=0;i// check IV, IX, XL, XC, CD, CM
       if(i!=N-1){ 
          int n=map[s[i]-'A'];
          int nn=map[s[i+1]-'A']; 
             if(n
               sum+=(nn-n);
               i++;
             }else{
               sum+=n;
        }
        }else
            sum+=map[s[i]-'A'];
    }
    return sum;
}

2015年7月30日 星期四

LEET code--Integer to Roman


Integer to Roman


Given an integer, convert it to a roman numeral.

Input is guaranteed to be within the range from 1 to 3999.


簡單  值觀就是直接暴力法了

麻煩的是
4 9 40 90 400 900
要另外處理


/*
I=1 V=5 X=10 L=50 C=100 D=500 M=1000
IV=4 IX=9 XL=40 XC=90 CD=400 CM=900
*/

char* intToRoman(int num) {
    int size=0;
    char *ans;
    int i=0;
    while(num!=0){
        if(num/1000){
            for( i=0;i                ans[size++]='M';
             
            }
            num-=1000*(i);
         
        }
        if(num/900){
            ans[size++]='C';
            ans[size++]='M';
            num-=900;
        }
        if(num/500){
            for( i=0;i                ans[size++]='D';  
            }
            num-=500*(i);;
        }
        if(num/400){
            ans[size++]='C';
            ans[size++]='D';
            num-=400;
        }
        if(num/100){
            for( i=0;i                ans[size++]='C';  
            }
            num-=100*(i);
        }
        if(num/90){
            ans[size++]='X';
            ans[size++]='C';
            num-=90;
        }
        if(num/50){
            for( i=0;i                ans[size++]='L';  
            }
            num-=50*(i);
        }
        if(num/40){
            ans[size++]='X';
            ans[size++]='L';
            num-=40;
        }
        if(num/10){
            for( i=0;i                ans[size++]='X';  
            }
            num-=10*(i);
        }
        if(num/9){
            ans[size++]='I';
            ans[size++]='X';
            num-=9;
        }
        if(num/5){
            for( i=0;i                ans[size++]='V';  
            }
            num-=5*(i);
        }
        if(num/4){
            ans[size++]='I';
            ans[size++]='V';
            num-=4;
        }
        if(num){
            for( i=0;i                ans[size++]='I';  
            }
            num-=1*(i);
        }
    }
    ans[size]='\0';
    return ans;
}

LEET code--Palindrome Number

Palindrome Number

Determine whether an integer is a palindrome. Do this without extra space.

簡單  把之前寫好的反轉int直接拿來用

會發現不會過
原來負數都不算
是負的直接略過


int reverse(int x) {
    int ans=0;
    while(x!=0){
        if(ans > INT_MAX/10 || ans< INT_MIN/10 )return 0;
        ans*=10;
        ans+=x%10;
        x/=10;
    }
    return ans;
}

bool isPalindrome(int x) {
    if (x < 0) {
        return false;
    }
    return x==reverse(x) ? true:false;
}

LEET code-Reverse Integer



Reverse digits of an integer.

Example1: x = 123, return 321
Example2: x = -123, return -321

可能會overflow
一開始的寫法想太複雜
還先去算長度
如果長度==10
在去作處理
但是根本只要到 9位數在判斷就好
因為要超過INT_MAX或是INT_MIN的尾數 在還沒反轉之前就會先overflow了
所以第9位在判斷就好






int reverse(int x) {
    int ans=0;
    while(x!=0){
        if(ans > INT_MAX/10 || ans< INT_MIN/10 )return 0;
        ans*=10;
        ans+=x%10;
        x/=10;
    }
    return ans;
}