本文正在参加「金石方案 . 分割6万现金大奖」

前语

  • iOS日常开发中, 算法运用的多吗? 实事求是的来说, 是不多的.
  • 那算法的学习对iOSer来说, 就不需求了吗? 答案是很需求.
  • iOS的日常开发中, 用到的算法确实不多, 可是算法在iOS开发里面的应用都被封装在各种常用API的内部了.
  • 对算法的学习, 能够提高对iOS底层的了解与知道, 这些算法的常识是计算机技术领域通用的. 下面就iOS开发中一些经典的算法进行一个简单的整理.
  • 文章纯手打, 抛砖引玉, 如有过错还请谈论区指正, 先行谢过了:)

1. 字符串回转

  • 编写一个函数,其作用是将输入的字符串回转过来。输入字符串以字符数组s的形式给出。不要给另外的数组分配额定的空间,你必须原地修正输入数组、运用 O(1) 的额定空间解决这一问题。

示例 1:

输入: s = ["h","e","l","l","o"]
输出: ["o","l","l","e","h"]

示例 2:

输入: s = ["H","a","n","n","a","h"]
输出: ["h","a","n","n","a","H"]
  • 运用C言语的解答及思路:
void reverseString(char* s, int sSize) {
    // 指向第一个字符 
    char *begin = s; 
    // 指向最终一个字符 
    char *end = s + sSize - 1; 
    while (begin < end) { 
        // 交流前后两个字符, 一起移动指针 
        char temp = *begin; 
        *(begin++) = *end; 
        *(end--) = temp; 
    } 
}
  • 力扣链接

2. 单链表回转

  • 给你单链表的头节点head,请你回转链表,并回来回转后的链表。如:
输入: head = [1,2,3,4,5]
输出: [5,4,3,2,1]

iOS老司机整理, iOSer必会的经典算法_1

  • 选用头插法的思路图解:

iOS老司机整理, iOSer必会的经典算法_1

  • 运用Swift言语的解答及思路:
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public var val: Int
 *     public var next: ListNode?
 *     public init() { self.val = 0; self.next = nil; }
 *     public init(_ val: Int) { self.val = val; self.next = nil; }
 *     public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
 * }
 */
class Solution {
    // 递归遍历
    // func reverseList(_ head: ListNode?) -> ListNode? {
    //     if head == nil || head?.next == nil {
    //         return head
    //     }
    //     var newHead = reverseList(head?.next)
    //     head?.next?.next = head
    //     head?.next = nil
    //     return newHead
    // }
    // 头插法
    func reverseList(_ head: ListNode?) -> ListNode? {
        var prev : ListNode? = nil // 新建上一个结点点, 初始为nil
        var current : ListNode? = head // 设置当时结点为传入的结点
        while current != nil {// while遍历当时结点
            let next : ListNode? = current?.next // 设置下一个结点为当时结点的next
            current?.next = prev // 当时结点的next节点指向上一个结点
            prev = current // 设置上一个结点为当时结点
            current = next // 设置当时结点为下一个结点
        } 
        return prev // 回来头插的结点
    }
}
  • 力扣链接

3. 有序数组兼并

  • 如何将有序数组a和b的值兼并到一个数组c傍边, 且仍然坚持有序?
  • 算法思路:
  • 利用双指针.
    iOS老司机整理, iOSer必会的经典算法_1
  • 运用C言语的解答及思路:
void mergeArray(int a[], int aLen, int b[], int bLen, int c[]) {
    // 遍历数组a的指针
    int p = 0;
    // 遍历数组b的指针
    int q = 0;
    // 记载当时存储位置
    int i = 0;
    // 任一数组没有到达边界则进行遍历
    while (p < aLen && q < bLen) {
        // 假如a数组对应位置的值小于b数组对应位置的值
        if (a[p] <= b[q]) {
            // 存储a数组的值
            c[i] = a[p];
            // 移动b数组的遍历指针
            p++;
        }
        else {
            // 存储b数组的值
            c[i] = b[q];
            // 移动b数组的遍历指针
            q++;
        }
        //指向兼并成果的下一个存储位置
        i++;
    }
    // 假如a数组有剩下
    while (p < aLen) {
        // 将a数组剩下部分拼接到兼并成果的后边
        c[i] = a[p++];
        i++;
    }
    // 假如b数组有剩下
    while (q < bLen) {
        // 将b数组剩下部分拼接到兼并成果的后边
        c[i] = b[q++];
        i++;
    }
}
    // 验证代码:
    // 有序数组归并
  int a[5] = {1, 3, 5, 7, 12};
  int b[7] = {2, 4, 6, 8, 9, 10, 11};
  // 用于存储归并成果
  int c[12];
  // 归并操作
  mergeArray(a, 5, b, 7, c);
  // 打印归并成果
  printf("merge result is ");
  for (int i = 0; i < 12; i++) {
    printf("%d ", c[i]);
  }
  • 成果打印:
    iOS老司机整理, iOSer必会的经典算法_1

发文不易, 喜欢点赞的人更有好运气 :), 定期更新+关注不迷路~

ps:欢迎参加笔者18年树立的研究iOS审阅及前沿技术的三千人扣群:662339934,坑位有限,备注“网友”可被群管经过~

本文正在参加「金石方案 . 分割6万现金大奖」