2015年7月29日 星期三

LEET CODE-ZigZag Conversion

ZigZag Conversion

 The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)
P   A   H   N
A P L S I I G
Y   I   R
And then read line by line: "PAHNAPLSIIGYIR"
Write the code that will take a string and make this conversion given a number of rows:
string convert(string text, int nRows);
convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR".

一開始根本不懂她的規律到底是怎樣
查了一下原來是

 nRows = 3
0   4   8  ...
1 3 5 7 9
2   6   10
 nRows = 4
0     6       12 ...
1   5 7    11
2 4   8 10  
3     9





每一個row的跳躍剛好是 2*(nRows - 1)
所以算好就好了

原本一開始用char ans [size]
但是超過一次的測資會爆炸
char *ans=(char*)malloc(sizeof(size)*sizeof(char));
也會爆炸
乾脆不先要求記憶體
直接char *ans;  就再也沒有run time error.....
可能題目有限制記憶體大小?
(最下面更新了!!)

remin 是在row!=0 and row!=numRows-1 的狀態下多出來了

numRows=4的情況下
row1 會是 1 5 7 11
1->5:4
5->7:2
兩個加起來一定會是6
所以每次都會選擇要加哪個數字
後來想想好像多此一舉

可以改成
        ans[count]= s[index];
        index=index+jump;
        if( row!=0 || row!=numRows-1 ){
         ans[++count]= s[index]+2*(numRows-1-row);
}
     
        if( index >= size ){
            row++;
            index=row;
           // remin= ( row==0 || row==numRows-1 ? jump: 2*(numRows-1-row) ) ;
        }


PS:
char *s
可以用strlen算長度
我每次都忘記了....


----------------------------
SyntaxHighlighter   又不能用了FFFFFFFFFFF

char* convert(char* s, int numRows) {
    int size= strlen(s);
//printf("%d",size);
    if(numRows == 1 || size==1) return s;
    int jump = numRows *2 -2;
    //char *ans=(char*)malloc(sizeof(size)*sizeof(char));
    char *ans;
    //char ans[size];
    //memset(ans,'\0',size);
    //ans[size]='\0';
    int row=0, remin=2*(numRows-1),index=0;
    for(int count=0;count   
        ans[count]= s[index];
        index=index+remin;
        remin= ( row==0 || row==numRows-1 ? jump: jump-remin ) ;
        if(index >= size){
            row++;
            index=row;
            remin= ( row==0 || row==numRows-1 ? jump: 2*(numRows-1-row) ) ;
        }
     
    }
    ans[size]='\0';
    return ans;
}



-----------------------------
神人寫法:
簡單明瞭阿!!!!

char* convert(char* s, int numRows) { int n=strlen(s); char* a; int k=0; if(numRows==1 || n<=numRows)return s; for(int i=0;i { for(int j=i;j { a[k++]=s[j]; if(i!=0 && i!=numRows-1) { int t=j+2*(numRows-1)-2*i; if(t<n) a[k++]=s[t]; } } } a[k]='\0'; return a;
}


----------------------------------
我後來發現我哪邊寫錯了....
char *ans=(char*)malloc(size*sizeof(char)+1);
我之前把size也用sizeof.....

char* convert(char* s, int numRows) {
    int size=0;
    while(s[size] !='\0')size++;
    
    //int size= strlen(s);
//printf("%d",size);
    if(numRows == 1 || size==1) return s;
    int jump = numRows *2 -2;
    char *ans=(char*)malloc(size*sizeof(char)+1);
    //char *ans;
    //char ans[size];
    //memset(ans,'\0',size);
    //ans[size]='\0';
    int row=0, remin=2*(numRows-1),index=0;
    for(int count=0;count
      //  printf("row= %d,s[index]=%c,index=%d,remin=%d\n",row,s[index],index,remin);
        ans[count]= s[index];
        index=index+remin;
        remin= ( row==0 || row==numRows-1 ? jump: jump-remin ) ;
        if(index >= size){
            row++;
            index=row;
            remin= ( row==0 || row==numRows-1 ? jump: 2*(numRows-1-row) ) ; 
        }
        
    }
    ans[size]='\0';
    return ans;
    
    

}

C 筆記 char 用strlen

The array declaration char a[6]; requests that space for six characters be set aside, to be known by the name a. That is, there is a location named a at which six characters can sit. The pointer declaration char *p; on the other hand, requests a place which holds a pointer. The pointer is to be known by the name p, and can point to any char (or contiguous array of chars) anywhere.
The statements
 char a[] = "string";
 char *p = "string"; 
would result in data structures which could be represented like this:
     +---+---+---+---+---+---+----+
  a: | s | t | r | i | n | g | \0 |
     +---+---+---+---+---+---+----+
     +-----+     +---+---+---+---+---+---+---+ 
  p: |  *======>; | s | t | r | i | n | g |\0 |    
     +-----+     +---+---+---+---+---+---+---+ 
It is important to realize that a reference like x[3] generates different code depending on whether xis an array or a pointer. Given the declarations above, when the compiler sees the expression a[3], it emits code to start at the location a, move three elements past it, and fetch the character there. When it sees the expression p[3], it emits code to start at the location p, fetch the pointer value there, add three element sizes to the pointer, and finally fetch the character pointed to. In the example above, both a[3] and p[3] happen to be the character l, but the compiler gets there differently.

char *p = "string"; 
用strlen算長度,不要用sizeof
因為sizeof試算pointer長度


2015年7月28日 星期二

LEET code--Longest Substring Without Repeating Characters

Longest Substring Without Repeating Characters

 Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.

找出連續且每個字元都不一樣的數列
一開始用爆力法,但是會超過時間....
只好去翻discuss
有人很厲害的把數列enumerate
接著每次看到一個字元,就轉成int 就進一個ASC[255]的陣列
該陣列記錄每個ASC字元 上次存在的enumerate數字多少
如果重複就把該數字的前一個位置enumerate找出來 減掉之後就是最常的長度
EX:
A  B C E  D  F  G  H  I   J    A   Z Q   W  B
1  2  3 4  5   6  7  8   9  10 11 12 13 14 15
第11的時候,去ASC[255]發現重複A在第1個位置, 把1記錄下來,現在最常的長度就是11-1=10
在第15的時候,B重複 再2的位置-->15-2=13的連續長度

想到這個真的很猛


class DemoApp {
    int lengthOfLongestSubstring(char* s) {
    int asc[255];
    if(*s == '\0')return 0;
    memset(asc,0,sizeof(asc));
    char *pos=s;
    int repeat=0;
    int count=0;
    int length=0;
    while( (*pos) != '\0' ){
        if( asc[*pos]!=0 )repeat= (  asc[*pos] > repeat ?  asc[*pos]:repeat  );
       
        asc[ *pos]=++count;
        if((count- repeat)>length )length=count- repeat;
        pos++;
    }
    length = ( length==0 ? count:length );
    return length;
    //    give the sequence number of the s,  if find out a repeat-> remember the number
    //
   
}
}


LEET code -Add Two Numbers

Add Two Numbers

 You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8

一開始看不懂題目
範例的意思是 342+564=708  把她算出來
只是現在是反過來的
就只是簡單的指標運用
class DemoApp {
    struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
    
   

   // if( l1 == NULL || l2 == NULL)return NULL;
    int incr=0;
    int sum=0;
    struct ListNode* point = (struct ListNode *)malloc(sizeof(struct ListNode));
    point->val=0;
    point->next=NULL;
    struct ListNode* ansRoot=point;
    while(l1 || l2 ||incr)
    {
        sum = ( l1!=NULL ?   l1->val:0)+(l2!=NULL ? l2-> val:0)+incr;
        incr = sum/10;
        sum%=10;
       // struct ListNode *temp = (struct ListNode*)malloc(sizeof(struct ListNode));
       // point->val=sum;
        point->next=(struct ListNode *)malloc(sizeof(struct ListNode));
        point = point->next;
        point->val=sum;
        point->next=NULL;
        
        if(l1)l1=l1->next;
        if(l2)l2=l2->next;
        
    }
    ansRoot=ansRoot->next;
    return ansRoot;
    
}
}


LEET code-Two Sum

Two Sum

 Given an array of integers, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
反正就是找出哪兩個加起來會是target
又只會有一組  就直接找
概念是
先sort一遍  從小排到大
兩個指標left and right
從數列的最開頭跟最尾端開始
left=nums[0]
right=nums[numsSize-1]
如過left+right > target
因為已經排列過 所以可以確定是right太大
讓她往左一一格
left+right < target
就是left 太小   向右一格

找到答案放到ANS陣列
因為答案要求的是要沒經過排序過的  所以要把原始位置再找出來


PS: 這邊用SyntaxHighlighter 會奇怪字元出現,懶得找BUG


int compare(const void *arg1, const void *arg2) {
  int compare(const void *arg1, const void *arg2) {
  return  (*(int *)arg1 - *(int *)arg2);
}
int* twoSum(int* nums, int numsSize, int target) {

    
    
    int* ans= (int *)malloc(sizeof(int)*2);
    int* temp = (int *)malloc(sizeof(int)*numsSize);
    memcpy(temp,nums,numsSize*sizeof(int));
    qsort( (void*)temp, numsSize, sizeof(int) ,compare) ;
    int find=0;
    int left=0;
    int right=numsSize-1;
    while(left
        if(temp[left]+temp[right]   >target){
            right--;
        }else if(temp[left]+temp[right]< target){
            left++;
        }else {
            ans[0]=temp[left];
            ans[1]=temp[right];
           // ans[0]=10;
            break;
        }
        
    }
    //ans[0]=10;
    
    int flag=0;
    for(int i=0;i
        if(ans[0]==nums[i]){
            ans[0]=i+1;
            flag++;
        }
        else if(ans[1]==nums[i] ){
            ans[1]=i+1;
            flag++;
        }
        if(flag>=2){
            if(ans[0]>ans[1]){
                int temp=ans[1];
                ans[1]=ans[0];
                ans[0]=temp;
            }
            break;
        }
    }
    
    free(temp);
    return ans;
}



用SyntaxHighlighter 在google的 Blogger


當初網路上找一堆
人家教學怎麼用都不對
重於找到一個可以用的
記錄!!!

1.
去範本-->網誌即時狀態的編輯HTML

2.再 /head 的前一行 貼入以下的CODE
 
    


    }

3.
測試
 
 
 
    int workkkkk(){
        int yessssss=1;
    }


4.
結果

 
    int workkkkk(){
        int yessssss=1;
    }

LEET code--Median of Two Sorted Arrays

LEET code--Median of Two Sorted Arrays
There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

一開始直觀  就是先檢查有沒有一個數列完全比另外一個大,但是這樣做會讓CODE變長LOL

接著在去慢慢比較找中位數

這是比較笨的寫法,看到有人用更神的
還要再學習阿~



int checkoverlap(int* nums1, int nums1Size, int* nums2, int nums2Size){
    int flag=0;
    
    if(nums1[ nums1Size-1 ] < nums2[0] ){//nums1 is less than 2
        return 1;
    }else if(nums2[ nums2Size-1 ] < nums1[0]){//nums2 is less than 1
        return 2;
    }else {// overlap
        return 3;
    }
    
}
double case1(int* nums1, int nums1Size, int* nums2, int nums2Size){
    int medin=(nums1Size+nums2Size)/2 +1 ;//because the devide won't round up   5/2=2,6/2=3
    
    if( nums1Size < medin ){//inside the nums2
        if( (nums1Size+nums2Size)%2==0 ){
            return ( (medin-nums1Size ==1) ? (nums1[nums1Size-1]+nums2[0])/2.0 : (nums2[medin - nums1Size-1]+nums2[medin - nums1Size-2] )/2.0 );
                    //medin is in the first nums2: not in the first
        }else {
            return nums2[medin - nums1Size -1 ];
        }
                
    }else if( nums1Size > medin ){//inside the nums1
        return ( ((nums1Size+nums2Size)%2==0 ) ?  (nums1[medin -1]+nums1[medin -2] )/2.0 : nums1[medin  -1 ]  );
                //even: odd
    }else if( nums1Size == medin ){//medin is in the last number of nums1
        return ( (nums1Size+nums2Size)%2==0 ?  (nums1[nums1Size-1] + nums1[nums1Size-2]  )/2.0 : nums1[nums1Size-1] );
                //even, last2 number in nums1: last number in nums1
    }
}

double case2(int* nums1, int nums1Size, int* nums2, int nums2Size){
    int medin=(nums1Size+nums2Size)/2 +1 ;//because the devide won't round up   5/2=2,6/2=3
    if( nums2Size < medin ){//inside the nums1
        if( (nums1Size+nums2Size)%2==0 ){
            return ( (medin-nums2Size ==1) ? (nums2[nums2Size-1]+nums1[0])/2.0 : (nums1[medin - nums2Size-1]+nums1[medin - nums2Size-2] )/2.0 );
                    //medin is in the first nums2: not in the first
        }else {
            return nums1[medin - nums2Size -1 ];
        }
                
    }else if( nums2Size > medin ){//inside the nums2
        return ( ((nums1Size+nums2Size)%2==0 ) ?  (nums2[medin -1]+nums2[medin -2] )/2.0 : nums2[medin  -1 ]  );
                //even: odd
    }else if( nums2Size == medin ){//medin is in the last number of nums1
        return ( (nums1Size+nums2Size)%2==0 ?  (nums2[nums2Size-1] + nums2[nums2Size-2]  )/2.0 : nums2[nums2Size-1] );
                //even, last2 number in nums1: last number in nums1
    }
}


double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) {
    if(nums1Size==0){
         if(nums2Size ==1)return nums2[0];
        return ( nums2Size%2==0 ? (nums2[nums2Size/2]+nums2[(nums2Size/2) - 1])/2.0  : nums2[nums2Size/2] );//even:odd
    }
    if(nums2Size==0){
        if(nums1Size ==1)return nums1[0];
        return ( nums1Size%2==0 ? (nums1[nums1Size/2]+nums1[nums1Size/2 - 1])/2.0  : nums1[nums1Size/2] );
    }
    //find the overlap
    int medin=(nums1Size+nums2Size)/2 +1 ;//because the devide won't round up   5/2=2,6/2=3
    int sum= nums1Size + nums2Size;
    int nums1P,nums2P,remin=0;
    int previous=0,current=0;
    
    switch ( checkoverlap( nums1,  nums1Size,  nums2,  nums2Size) ){
        case 1://nums1 < nums2
            return case1( nums1,  nums1Size,  nums2,  nums2Size);
        
            break;
        case 2://nums2 < nums1
            return case2( nums1,  nums1Size,  nums2,  nums2Size);
            break;
        case 3://overlap nums1  nums2
            
            nums1P=nums2P=1;
            //count how many number need to process
            remin=medin;
            while ( nums2P<=nums2Size || nums1P<=nums1Size ){
                if( nums1P<= nums1Size  && nums1[nums1P-1] <= nums2[nums2P -1] ){
                    previous = current;
                    current = nums1[nums1P-1];
                    nums1P++;
                    remin--;
                    
                    
                    //if( nums1P > nums1Size)remin--;
                }else if(  nums2P<=nums2Size && nums2[nums2P -1 ] < nums1[nums1P - 1] ){
                    previous = current ;
                    current = nums2[nums2P-1];
                    nums2P++;
                    remin--;
                    
                    
                    //if( nums2P > nums2Size)remin--;
                }else if( nums2P > nums2Size ){
                    previous = current;
                    current = nums1[nums1P-1];
                    nums1P++;
                    remin--;

                }else if( nums1P > nums1Size){
                    previous = current ;
                    current = nums2[nums2P-1];
                    nums2P++;
                    remin--;
                }
                if(remin<=0 ){
                    return ( ((nums1Size+nums2Size)%2==0 ) ?  (previous+ current)/2.0 :current);
                    break;
                }
            }
            
            
            break;
    }
    
}