算法题集锦

1.判断一个单向链表是否存在环,并且找到环入口。

https://www.jianshu.com/p/ef71e04241e4

2.删除链表的倒数第n个位置。

#import "SinglyLinkedList.h"

/**
 给定一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点
 输入:head = [1,2,3,4,5], n = 2
 输出:[1,2,3,5]
 输入:head = [1,2], n = 1
 输出:[1]
 */
// 2
LinkList removeNthFromEnd(LinkList head, int n) {
    if (n < 1) {
        return head;
    }
    LinkList fast = head->next;
    LinkList slow = head;
    // fast slow固定的间隔
    for (int i = 0; i < n; ++i) {
        if (!fast) {
            return head;
        }
        fast = fast->next;
    }
    
    while (fast) {
        fast = fast->next;
        slow = slow->next;
    }
    slow->next = slow->next->next;
    return head;
}

int main(int argc, const char * argv[]) {
    Status iStatus;
    LinkList L;
    iStatus = createLinkList(&L);
    for(int j=1; j<=10; j++)
    {
        insertElemByIndex(&L, 1, j);
    }
    printList(L);
    L = removeNthFromEnd(L, 2);
    printList(L);
    return 0;
}

2.反转链表。

头插法即可

3.斐波那契数列解法

1)递归

int fib(int n)
{
    if (n <= 2) return 1;
    else return fib(n-1) +fib(n-2);
}

2)动态规划

/**
 Dp ->动态规划
 3 + n-1 + n-2 = 2n
 O(n)
 */
int fib2(int n)
{
    int f[n+1];
    f[1] = f[2] = 1;
    for (int i = 3; i <= n; i++)
        f[i] = f[i-1] + f[i-2];
    return f[n];
}

/**
 Dp ->动态规划
 
 O(n)
 */
int fib3(int n)
{
    int a = 1, b = 1;
    for (int i = 3; i <=n ; i++) {
        int c = a + b;
        a = b;
        b = c;
    }
    return b;
}

3)矩阵

struct Matrix {
    int mat[2][2];
};

struct Matrix matrixMultiply(struct Matrix* a, struct Matrix* b) {
    struct Matrix c;
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            c.mat[i][j] = (*a).mat[i][0] * (*b).mat[0][j] + (*a).mat[i][1] * (*b).mat[1][j];
        }
    }
    return c;
}
// m^n =
void matpow(int n, struct Matrix *m) {
    struct Matrix q;
    q.mat[0][0] = q.mat[0][1] = q.mat[1][0] = 1;
    q.mat[1][1] = 0;
    for (int i = 0; i < n; i++)
        *m = matrixMultiply(m, &q);
}

/**
 矩阵
 时间复杂度:O(n)。
 空间复杂度:O(1)。
 */
int fib4(int n)
{
    if (n < 2) {
      return n;
    }
    // 单位矩阵
    struct Matrix ret;
    ret.mat[0][0] = ret.mat[1][1] = 1;
    ret.mat[0][1] = ret.mat[1][0] = 0;
    matpow(n-1, &ret);
    return ret.mat[0][0];
}
/**
 O(logn)
 O(n)
            n = 8 *1/2 = 4
 m^n = 2^n = 2^8 =    (2⁴)² = ((2²)²)²
 (2⁴)² * 2
  */
void matpow2(int n, struct Matrix *m) {
    if (n > 1) {
        matpow2(n/2, m);
        *m = matrixMultiply(m, m);
    }
    //
    if (n & 1) {
        struct Matrix q;
        q.mat[0][0] = q.mat[0][1] = q.mat[1][0] = 1;
        q.mat[1][1] = 0;
        *m = matrixMultiply(m, &q);
    }
}
/**
 通项公式
 O(1)
 */
int fib6(int n) {
    double sqrt5 = sqrt(5);
    double fibN = pow((1 + sqrt5) / 2, n) - pow((1 - sqrt5) / 2, n);
    return round(fibN / sqrt5);
}


你可能感兴趣的:(算法篇,算法)