2015年8月27日 星期四

LEET code-- Linked List Cycle II


Linked List Cycle II


Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
Note: Do not modify the linked list.
Follow up:
Can you solve it without using extra space?


這題很奸詐阿
沒寫過當場要想出來我覺得太難了
硬幹 不好
要先利用再 linked list cycle I的觀念找出是哪一點(meeting)有發現循環
利用meeting指標 跟temp指標來找出head在哪
因為兩個會同時到達cycle head
解釋如下

head: list head
E: the head of the cycle
X: the meeting point of the fast and slow pointer in the Linked list cycle I  
H: distance from head to cycle entry E (head到E的長度) D: distance from E to X (E到X的長度) L: cycle length (cycle的長度) _____ / \ head_____H______E \ \ / X_____/ 因為fast and slow會同時到達X點
對slow而言 他走了 H+D這麼長才到X點
對fast而言 他走了 2(H+D)的長度才跟slow碰面
但是!!!
fast 可能已經走了好幾圈了,可能已經繞了n圈
所以他而外多走了n*L這些距離
所以會變成 H+D+n*L=2(H+D)
H = (n-1)*L + (L-D)
你會發現 H的長度會跟L-D的距離一樣
所以我們可以利用X的指標,讓他跟另外一個從head開始走的指標一起比較
兩個同時都往下走,因為走的距離一樣,當發現兩個指到同一個東西的時候就會剛好是E




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode * hasCycle(struct ListNode *head) {
    if(head==NULL)return NULL;
    struct ListNode * fast=head;
    struct ListNode * slow=head;
    
    while(fast && fast->next && fast->next->next){
        fast=fast->next->next;
        slow=slow->next;
        if(fast == slow)return slow;
    }
    if(fast->next == NULL || fast->next->next==NULL)return NULL;
}
struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode * meeting=NULL;
    struct ListNode * temp=head;
    meeting = hasCycle(head);
    if(meeting == NULL)return NULL;
    
    while(temp && temp->next){
        if(temp == meeting)return temp;
        meeting=meeting->next;
        temp=temp->next;
    }
}




2015年8月24日 星期一

LEET code--single number ||

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




下面是解釋
------------
The key to solve this problem is the count of 1s of each bit of all numbers.
Take one bit number for example: nums = [1, 1, 1, 0, 0, 0, ..., x] . All numbers are 0 or 1.
We know that every number appears three times except for just one number. So, if the count of 1s in nums is 0, 3, 6, ..., 3 * n, then the single number is 0. And if the count of 1s in nums is 1, 4, 7, ..., 3*n+1, then the single number is 1.
So, for an array " nums " that contains only 0 or 1, the code to find the single number are:
count = 0
for num in nums:
    count = (count + num) % 3
return count
To make "count" less than 3, mod "count" with 3 in every loop.
Below is the procedure for finding the single number in [1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]:
Table 1:
++=======++===+===+===+===+===+===+===+===+===+===+===+===+===+====++
|| num   ||   | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0  ||
++-------++---+---+---+---+---+---+---+---+---+---+---+---+---+----++
|| count || 0 | 1 | 1 | 2 | 0 | 0 | 1 | 1 | 2 | 2 | 0 | 0 | 1 | 1* ||
++=======++===+===+===+===+===+===+===+===+===+===+===+===+===+====++
So the single number is 1.
We can write the calculate table for expression "count' = (count + num) % 3":
Table 2:
++=======+=====+========++
|| count | num | count' ||
++-------+-----+--------++
||   0   |  0  |   0    ||
++-------+-----+--------++
||   1   |  0  |   1    ||
++-------+-----+--------++
||   2   |  0  |   2    ||
++-------+-----+--------++
||   0   |  1  |   1    ||
++-------+-----+--------++
||   1   |  1  |   2    ||
++-------+-----+--------++
||   2   |  1  |   0    ||
++-------+-----+--------++
To extend this algorithm to 32bits number. We need to rewrite these code to bit operation expressions.
And the key is rewriting the expression " count' = (count + num) % 3 " to bit operation expressions.
Write binary numbers of " count " and " count' " in "Table 2". And split their bits into two column:
Table 3:
++=======+============+=====+============+========++
||       |    count   | num |   count'   |        ||
|| count |    (bin)   |     |   (bin)    | count' ||
|| (dec) ++=====+=====+=====+=====+=====++ (dec)  ||
||       || b1  | b0  | num | b1' | b0' ||        ||
++-------++-----+-----+-----+-----+-----++--------++
||   0   ||  0  |  0  |  0  |  0  |  0  ||   0    ||
++-------++-----+-----+-----+-----+-----++--------++
||   1   ||  0  |  1  |  0  |  0  |  1  ||   1    ||
++-------++-----+-----+-----+-----+-----++--------++
||   2   ||  1  |  0  |  0  |  1  |  0  ||   2    ||
++-------++-----+-----+-----+-----+-----++--------++
||   0   ||  0  |  0  |  1  |  0  |  1  ||   1    ||
++-------++-----+-----+-----+-----+-----++--------++
||   1   ||  0  |  1  |  1  |  1  |  0  ||   2    ||
++-------++-----+-----+-----+-----+-----++--------++
||   2   ||  1  |  0  |  1  |  0  |  0  ||   0    ||
++=======++===========+=====+===========++========++
Here comes the hardest part of this solution.
"Table 3" is a truth table, we need to use it to find the formulas to calculate " b0' " and " b1' ":
b0' = f(b1, b0, num)
b1' = g(b1, b0, num)
With observations, guesses, experiments and even some luck. Finally I got two simple and elegant formulas:
b0' = (b0 ^ num) & (~b1)
b1' = (b1 ^ num) & (~b0')
or
int nb0 = (~b1 & b0 & ~num) | (~b1 & ~b0 & num);
int nb1 = (b1 & ~b0 & ~num) | (~b1 & b0 & num) ;

The AC code:
class Solution:
    # @param {integer[]} nums
    # @return {integer}
    def singleNumber(self, nums):
        b1, b0 = 0, 0
        for num in nums:
            b0 = (b0 ^ num) & (~b1)
            b1 = (b1 ^ num) & (~b0)
        return b0

-----------



2015年8月17日 星期一

LEET code --linked list cycle


Given a linked list, determine if it has a cycle in it.

我這方法不好 因為順序被我打亂了

好方法是   分兩個pointer
一個走比較慢  一個走比較快
如果快的會走到NULL  那就沒回圈
如果快地碰到曼的就代表有迴圈

為了增加處理速度 可以增加走的速度





 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
bool hasCycle(struct ListNode *head) {
    if(head==NULL)return false;
    struct ListNode* current=head;
    struct ListNode* previous=NULL;
    while(current!=NULL && current->next!=head){
        struct ListNode* next = current->next;
        current->next=previous;
        previous= current;
        current=next;
    }
    return (current==NULL) ? false:true;
}

---------------------------------------------
改版之後
用快慢pointer來指

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
bool hasCycle(struct ListNode *head) {
    if(head==NULL)return false;
    struct ListNode * fast=head;
    struct ListNode * slow=head;
    
    while(fast && fast->next && fast->next->next){
        fast=fast->next->next;
        slow=slow->next;
        if(fast == slow)return true;
    }
    if(fast->next == NULL || fast->next->next==NULL)return false;
    
}

LEET code--Add Digits

Add Digits

 Given a non-negative integer num, repeatedly add all its digits until the result has only one digit.
For example:
Given num = 38, the process is like: 3 + 8 = 111 + 1 = 2. Since 2 has only one digit, return it.







 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
int addDigits(int num) {
    while(num>=10){
        int temp=0;
        while(num!=0){
            temp+=num%10;
            num/=10;
        }
        num=temp;
    }
    return num;
}


2015年8月15日 星期六

S型脊椎側彎 矯正紀錄

從小從C型 到高中之後變成S型  但是很剛好的都不會痛

S型是 上20度 下20度
所以算是輕微的,之前看西醫,醫生都說反正2X歲了,都定型了,不要惡化就好
就再也沒理他

直到今年7月因為手受傷去中醫復健,那邊醫生突然冒出來一句"你是不是脊椎側彎"
我回"反正都2X了 也沒救了"
醫生"那是不會治的人,少部分會,我推薦你去看XXX,但是要自費,因為他健保難掛"

就這句話,衝了拉

------------------------------------------
從新竹到要那邊1個小時

我第一次掛自費,號碼就27號了
4點到那邊,只看到25號...

等到快5點,從終於有床位

醫生會問你要看什麼的,脊椎側彎就要你去照全身X光

照完之後,醫生還很納悶怎麼知道找他來做矯正,我就把故事跟他講
醫生覺得大概是學弟吧

醫生看X光發現我的S型轉的角度很奇怪,是麻煩的,但是事可以治好的!!

OS: 人生有救了?

醫生說他治很多個S型了,我不是第一個

----------------------------------------
第一次治療,因為有X光,所以護士會幫你用健保的,而不是自費(不然$$$$$$$$$$)

所以第一次才220
----------------------------------------
第二次 自療 自費要640  (哭哭  這時候才知道健保的好
治療內容主要就是他會要你做一堆奇怪的動作,每個星期都要去,還好我還是學生

---------------------------------------
醫生一直說 我是假的脊椎側彎   完全不知道位什麼......



2015年8月12日 星期三

LEET code --Search for a Range

Search for a Range


Given a sorted array of integers, find the starting and ending position of a given target value.
Your algorithm's runtime complexity must be in the order of O(log n).
If the target is not found in the array, return [-1, -1].

For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].

直觀就是直接找一次就好
一開始寫玩都不會對
搞半天
*returnSize 要給2



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
int* searchRange(int* nums, int numsSize, int target, int* returnSize) {
    *returnSize = 2;
    int *ans = (int *)malloc(sizeof(int) * *returnSize);
    ans[0]=-1;
    ans[1]=-1;
    if(numsSize == 0)return ans;
    if(target < nums[0] || target > nums[numsSize-1])return ans;
    for(int i=0;i<numsSize;i++){
        if(target == nums[i]){
            if(ans[0]==-1){
                ans[0]=i;
                ans[1]=i;
            }
            else ans[1]=i;
        }
        if(target<nums[i])break;
    }
    return ans;
}


如果要更快可以改用binary search
因為都排序好了
會兩倍快

LEET code --Merge Two Sorted Lists

Merge Two Sorted Lists

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

就兩個排序過的list 重新再組合
一開始有想過是不是可以用recursive
但是懶得去想




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
    if(l1==NULL)return l2;
    if(l2==NULL)return l1;
    struct ListNode* l1temp = l1;
    struct ListNode* l2temp = l2;
    
    while(l1temp != NULL && l2temp != NULL){
        if( l1temp->val >=l2temp->val){
            while(l2temp->next!=NULL){
                if( l2temp->next->val > l1temp->val){
                    break;
                }else{
                    l2temp=l2temp->next;
                }
            }
            struct ListNode* temp2=l2temp->next;
            l2temp->next = l1temp;
            l2temp = temp2;
      
        }else{
            while(l1temp->next!=NULL){
                if( l1temp->next->val > l2temp->val){
                    break;
                }else{
                    l1temp=l1temp->next;
                }
            }
            struct ListNode* temp=l1temp->next;
            l1temp->next = l2temp;
            l1temp=temp;
        }
    }
    return (l1->val >= l2->val)? l2:l1;
    
}


------------------------
recursive version
每次都跟自己比較
比較小的就去recursive 找 下一個可以比對方大的數字
這樣每次recursive 都會return最小值


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
    if (l1 == NULL)
        return l2;
    if (l2 == NULL)
        return l1;
    if (l1->val <= l2->val) {
        l1->next = mergeTwoLists(l1->next, l2);
        return l1;
    } else {
        l2->next = mergeTwoLists(l1, l2->next);
        return l2;
    }
}

2015年8月10日 星期一

Blogger 插入CODE

網路上還要抓套件什麼  

太麻煩了

用人家寫好的比較快拉!!!
http://hilite.me/

直接幫你轉換成HTML

要用的時候直接貼到HTML就好

LEET code--Remove Duplicates from Sorted List

Remove Duplicates from Sorted List

 Given a sorted linked list, delete all duplicates such that each element appear only once.
For example,
Given 1->1->2, return 1->2.
Given 1->1->2->3->3, return 1->2->3.


current 只有再future不一樣的時候才會前進
future會每次循環都向前

這樣是避免連續出現同樣數字,保留current的  讓future去找誰重複
如果沒有重複就current向前





 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
struct ListNode* deleteDuplicates(struct ListNode* head) {
    if(head==NULL)return head;
    struct ListNode *current=head;
    struct ListNode *future=head->next;
    while(current!=NULL && future!=NULL){
        if(current->val == future->val){
            current->next=future->next;
            free(future);
            future=(current !=NULL) ? current->next: NULL;
        }
        else{
            current=current->next;
            future=(current !=NULL) ? current->next: NULL;
        }
    }
    return head;
}

LEET code--Search Insert Position

Search Insert Position


Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
You may assume no duplicates in the array.

Here are few examples.
[1,3,5,6], 5 → 2
[1,3,5,6], 2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6], 0 → 0

寫到現在最簡單的一題,這居然不是正確率最高的...
第一次交出去,一次就對XD

反正如果一樣 或是 比目標大 就直接回傳該位置
不然就是最後回傳最後的位置

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


1
2
3
4
5
6
7
8
int searchInsert(int* nums, int numsSize, int target) {
    int i;
    for( i=0 ; i &lt; numsSize ; i++ )
    {
        if(target == nums[i] || nums[i]&gt;target)return i;
    }
    return numsSize;
}

LEET code --Excel Sheet Column Number

Excel Sheet Column Number


Related to question Excel Sheet Column Title
Given a column title as appear in an Excel sheet, return its corresponding column number.
For example:

    A -> 1
    B -> 2
    C -> 3
    ...
    Z -> 26
    AA -> 27
    AB -> 28 


原本還在想規律什麼  還跑去EXCEL 看之後到底怎麼排出來
後來突然想到  靠  這不就26進位而已嗎
繞一大圈  直接當作26進位來做就很快了


我算了一下 26進位在int的型態下 應該不會超過7~8位數
所以預先算好這些值,之後直接查表就好了
PS: 寫玩才想起來 明明有內建的可以call pow(26, (s.length() - i))
白癡....
而且 好像也不用需要那個涵式,直接每次*26 就好啦....
---------------------------------------



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
int titleToNumber(char* s) {
    int num[8];
    num[0]=1;
    for(int i=1;i<8-1;i++){
        num[i]=num[i-1]*26;
    }
    int size=strlen(s);
    int ans=0;
    if(size ==1)return s[0]-'A'+1;
    for(int i=0;i<size;i++){
        ans+=(s[i]-'A'+1)*num[size-i-1];
    }
    return ans;
}








------------------------------------
int titleToNumber(char* s) {
    int len = strlen(s);
    int num = 0;
    int GAP = 'A' - 1;
    for(int i = 0; i < len; ++i)
    {
        num = num * 26 + s[i] - GAP;
    }
    return num;
}

2015年8月9日 星期日

LEET code--Invert Binary Tree

Invert Binary Tree


Invert a binary tree.
     4
   /   \
  2     7
 / \   / \
1   3 6   9
to
     4
   /   \
  7     2
 / \   / \
9   6 3   1


超級簡單   指標全部互相交換就好
沒有到會有神人栽在這題


/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
struct TreeNode* invertTree(struct TreeNode* root) {
    if(root == NULL) return;
    struct TreeNode *temp=root->left;
    root->left=root->right;
    root->right=temp;
    invertTree(root->left);
    invertTree(root->right);
    return root;
}

2015年8月7日 星期五

LEET code--Same Tree

Same Tree

 Given two binary trees, write a function to check if they are equal or not.

Two binary trees are considered equal if they are structurally identical and the nodes have the same value.


檢查兩個樹 有沒有完全一致(結構上跟val)


bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
    if( p==NULL && q == NULL)return true;
    if( p==NULL && q!= NULL )return false;
    if( p!=NULL && q==NULL)return false;
    if(p->val != q->val)return false;
   
    bool le,ri;
    le=isSameTree(p->left,q->left);
    ri=isSameTree(p->right, q->right);
   
    return (le==false || ri==false)? false:true;
   
}



更好的寫法:
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
if(p == NULL && q == NULL) 
    return true;
if(p != NULL && q == NULL) 
    return false;
if(p == NULL && q != NULL) 
    return false;
if(p->val != q->val)
    return false;
return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}

直接用&& 改回傳只有true的方式  比較簡潔

LEET code--Delete Node in a Linked List

Delete Node in a Linked List


 Write a function to delete a node (except the tail) in a singly linked list, given only access to that node.

Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function.

一開始只給你要刪除的node的pointer
所以要把該刪除的node內部值改成下一個的
 像這樣
    p = node->next;
    if (!p) return;
    node->val = p->val;
    node->next = p->next;
    free(p);
P=上面範例的4
所以把3的內容改成4
再把4刪除
這樣3就不見了

但是更好的寫法是
如果不在乎刪除空間:
*node = *(node->next);
//直接把pointer的值改成下一個
*node是取pointer內部儲存的記憶體空間
直接改成*(node->next) 就可以把3變成4 (直接改記憶體位置)
如果要刪除空間:
struct ListNode* tofree = node->next;
*node = *(node->next);
free(tofree);

LEET code--Maximum Depth of Binary Tree

Maximum Depth of Binary Tree

Given a binary tree, find its maximum depth.

The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.


用recursive走一圈就知道
走到最後發現是null 就回傳0



int maxDepth(struct TreeNode* root) {
    if(root==NULL)return 0;
    int le=0,ri=0;
    le=maxDepth(root->left);
    ri=maxDepth(root->right);
   
    return (le > ri)? le+1:ri+1;
   
}

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;
}

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;
    
    

}