lecode算法题 小总结

.
.
.
.
.
.
.

1 打印9x9 乘法表


# python版
for i in range(1, 10):
    for k in range(1, i + 1):
        print(f'{i}X{k} \t', end='')
    print('\n')

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

# c版

#include <stdio.h>
int main()
{
    int i;
    int k;
    for (i = 1; i < 10; i++)
    {
        for (k = 1; k <= i; k++)
        { printf("%d x %d = %d  ", i, k, i * k);}
        printf("\n");
    }

    return 0;
}

# 外层循环控制层数,
# 内存循环控制每层 乘式的个数

.
.
.
.
.
.
.
.
.

2 判断一个数是由数组里面的哪两个数相加而成,如果有返回两个数的数组下标,注意不能是同一个数相加


l1 = [3, 5, 3, 4]
target = 6

# 错误解法:
def xxx():
    for i in l1:
        for k in l1:
            if l1.index(i) == l1.index(k):
                continue
            if i + k == target:
                return l1.index(i), l1.index(k)
        return None


res = xxx()
print(res)  # None
# 这个index方法只能获取目标元素,在数组中的下标位置,并且只返回第一个符合的元素位置
# 所以 按理我们需要返回的结果是(0,1)
# 但是第一次外层循环内层循环时,第一次迭代出的值通过判断直接break了,同理第二次迭代也break了
# 同理第二次外层循环内层循环时,也是两次迭代都是走到了break了
-------------------------------------------

# 解法1
def xxx():
    for i in range(0, len(l1)):
        for k in range(0, len(l1)):
            if i == k:
                continue
            if l1[i] + l1[k] == target:
                return i, k
        return None


res = xxx()
print(res)  # (0, 2)

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

# 解法2
# 一层for循环解决
def xxx():
    for i in range(0, len(l1)):
        res = target - l1[i]
        if res in l1:
            # 如果减出来的结果 在l1 里面,并且该值的下标和当前for循环的小标一样,就结束本次循环,继续下次循环
            if l1.index(res) == i:
                continue
            return i, l1.index(res)
    return None


res = xxx()
print(res)  # (2, 0)
# 但这种解法,多走步骤了,我们通过手动的将减出来的结果的下标与当前for循环的下标比较,如果一样就结束本次循环了
# 最好是减出来的结果,如果在l1里面,且不是当前for循环的值,就结束循环了,也就是第一次循环时,就能找到结果结束
# 返回(0,2) 这样的结果,才是最优解

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

# 解法3
def xxx():
    for i in range(0, len(l1)):
        res = target - l1[i]
        if res in l1:
            # 如果减出来的结果 在l1 里面,并且该值的下标和当前for循环的下标一样,那就获取下一个也是该减出来的结果的值的下标
            for index, k in enumerate(l1):
                if k == res:
                    if index == i:
                        continue
                    return i, index
    return None


res = xxx()
print(res)  # (0, 2)

# 还是两层for循环了,和第一种解法实际上没有本质区别,怎么压缩成1层for循环了???
------------------------------------------------

num_list = [3, 3, 4, 5, 3, 4, 1]
target = 8


def xxx():
    val_to_index_dict = {}   # 搞个空字典 里面准备放列表的值与索引的对应关系
    for i in range(0, len(num_list)):
        need_res = target - num_list[i]

        if need_res in val_to_index_dict:
 # 减出来的结果,在字典的键里面,说明之前的循环里面,将值作为键,下标索引作为值,放到了字典里面去了
          # 这个时候将之前放到字典里的键对的值,拿到就是对应列表里的索引下标
          # 这时候就结束了,之前放到字典里的列表索引下标,就是两数相加的左边的一个数的列表索引下标
          # 因为是之前循环放进去的,所以和本次循环的得到的数,一定不是列表里的同一个数!!!
            return val_to_index_dict[res], i

        if num_list[i] not in val_to_index_dict.keys():
            # 也就是本次迭代出的列表里的值,还没有作为键添加到字典里面
            # 就把该值作为键与列表里对应的索引作为值,放到字典里
            # 这里加这个if的判断还有一个好处,就是列表相同的元素,不会重复添加到字典里面
            # 也就是不会让相同值的元素,去更新字典里面的键对应的索引
            # 这样最后返出来的两个数组的下标,左边的下标一定是符合的,且最小的
            # 比如此处不加if判断,最后出的结果就是(1,3)  加了结果就是(0,3)
            val_to_index_dict[l1[i]] = i

    return None


# 整体的逻辑就是 根据列表 与 目标值
# 首先for循环列表,拿到列表里面元素的值,以及当前元素需要和一个什么数相加,才能等于目标值
# 然后判断这个需要的相加数need_res,在for循环开始前定义的空字典里面有没有,
# 如果有的话,就说明在之前循环的时候,已经将值作为键,下标索引作为值,放到了字典里面去了
# 这个时候寻找已经结束了

# 如果 当前列表迭代出的值,没有在字典里面添加过,
# 就添加到字典里面去,键是值,值是下标索引 加到字典里
# 比如我们第一次迭代的值是3,将3作为键,0作为值,放到字典里面去
# 第二次迭代的值是3,我们判断字典里面已经有键3了,
# 不需要再给字典里面键3对应的值,也就是索引更新了 字典里还是{3:0}

res = xxx()
print(res)  # (0, 3)

-----------------------------------------------
# 这样也行!!!
nums = [3,3,2, 7, 11, 15]
target = 5

def xxx():
    val_to_index ={}
    for i in range(4):
        now_res = nums[i]
        need_res = target-now_res
        if now_res not in val_to_index:
            val_to_index[now_res] = i
        if need_res in val_to_index and nums.index(need_res)!=i:
            return val_to_index[need_res],i
    return None

# 该算法的核心就是列表里面的不重复元素,转移字典里面去,值作为键,下标作为值
# 这样就不用两次for循环了!!!
# 其次就是直接上来先把for循环的列表元素如果没添加过,先添加到字典里面后,
# 然后再判断需要的值在不在字典里面,并且在加个限制条件保证这个需要的这个值,不是本次添加到字典里的值
# 让需要的值的索引不能等于当前添加到字典里的元素的键,因为如果一样了,那说明是同一个元素了,
# 本题要找的是两个不同的元素
res = xxx()
print(res)



-----------------------------------------------
# 测试用例
class Solution(object):
    def twoSum(self, nums, target):
        # 维护 val -> index 的映射
        val_to_index_dict = {}
        for i in range(len(nums)):
            # 查表,看看是否有能和 nums[i] 凑出 target 的元素
            need_res = target - nums[i]
            if need_res in val_to_index_dict:
                return [val_to_index_dict[need_res], i]
            if nums[i] not in val_to_index_dict.keys():
            # 存入 val -> index 的映射
                val_to_index_dict[nums[i]] = i
        return []

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

# c语言版

#include <stdio.h>

int twoSum(int *nums, int target, int sz)
{
    int i, j;
    for (i = 0; i < sz; i++)
    {
        int now_res = nums[i];
        int need_res = target - now_res;
        for (j = 0; j < sz; j++)
        {
            if (j == i)
            {
                continue;
            }
            if (nums[j] == need_res)
            {
                int arr1[] = {i, j};
                printf("%d  %d", arr1[0], arr1[1]);
                return 0;
            }
        }
    }
    int arr1[] = {999, 999};
    printf("%d  %d", arr1[0], arr1[1]);
    return 0;
}

int main()
{
    int nums[] = {2, 7, 11, 15};
    int target;
    scanf("%d", &target);
    int sz = sizeof(nums) / sizeof(nums[0]);
    int a = twoSum(nums, target, sz);
    return 0;
}

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


.
.
.
.
.
.
.
.
.
.
.
.

实现两个列表里面,相同索引位置元素的相加 的效果,模拟十进制相加的效果,低位在左,高位在右


def addTwoNumbers(l1, l2):
        res_list = []
        is_add = 0
        if len(l1) > len(l2):
            for i in range(len(l1)):
                if i < len(l2):
                    if (l1[i] + l2[i] + is_add )> 10:
                        res = l1[i] + l2[i] - 10 + is_add
                        is_add = 1
                        res_list.append(res)
                    else:
                        res_list.append(l1[i] + l2[i]+is_add)
                        is_add = 0
                if i >= len(l2):
                    if (l1[i] + is_add ) == 10:
                         res = 0
                         is_add = 1
                         res_list.append(res)
                    else:
                        res_list.append(l1[i]+is_add)
                        is_add = 0
        else:
            for i in range(len(l2)):
                if i < len(l1):
                    if (l1[i] + l2[i] + is_add )> 10:
                        res = l1[i] + l2[i] - 10 + is_add
                        is_add = 1
                        res_list.append(res)
                    else:
                        res_list.append(l1[i] + l2[i]+is_add)
                        is_add = 0
                if i >= len(l1):
                    if (l2[i] + is_add )== 10:
                         res = 0
                         is_add = 1
                         res_list.append(res)
                    else:
                        res_list.append(l2[i]+is_add)
                        is_add = 0
        if is_add == 1:
            res_list.append(1)
        return res_list

l1 = [9,9,9,9,9,9,9]
l2 = [9,9,9,9]

res = addTwoNumbers(l1,l2)
print(res)  # [8, 9, 9, 9, 0, 0, 0, 1]

.
.
.
.

冒泡排序


// 冒泡排序
#include <stdio.h>
void bubble_sort(int arr[], int sz)
{
    // 确定冒泡排序的趟数数组元素9个,冒泡排序就要排8趟
    int i = 1;
    for (i = 1; i < sz; i++)
    {
        // 每一趟冒泡排序
        int j = 0;
        for (j = 0; j < sz; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                int tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
    }
}

int main()
{
    int arr[] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
    int i = 0;
    int sz = sizeof(arr) / sizeof(arr[0]);
    // 对arr进行排序,排成升序
    bubble_sort(arr, sz);
    for (i = 0; i < sz; i++)
    {
        printf("%d \n", arr[i]);
    }
}

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

//                     9, 8, 7, 6, 5, 4, 3, 2, 1
// 冒泡排序第一趟后变成  8, 7, 6, 5, 4, 3, 2, 1, 9
// 冒泡排序第二趟后变成  7, 6, 5, 4, 3, 2, 1, 8, 9
// 冒泡排序第三趟后变成  6, 5, 4, 3, 2, 1, 7, 8, 9
//                     5, 4, 3, 2, 1, 6, 7, 8, 9
//                     4, 3, 2, 1, 5, 6, 7, 8, 9
//                     3, 2, 1, 4, 5, 6, 7, 8, 9
// 冒泡排序第七趟后变成  2, 1, 3, 4, 5, 6, 7, 8, 9
// 冒泡排序第八趟后变成  1, 2, 3, 4, 5, 6, 7, 8, 9
// 实际上,后续每趟的排序里面,已经不需要一直比到最后一个了,
// 第二趟排序的8就已经不需要再和9比较了,同理第八趟第0位与第1位比较互换数据后,就已经结束了

// 冒泡排序
#include <stdio.h>
void bubble_sort(int arr[], int sz)
{
    // 确定冒泡排序的趟数数组元素9个,冒泡排序就要排8趟
    int i = 1;
    for (i = 1; i < sz; i++)
    {
        // 每一趟冒泡排序
        int j = 0;
        // sz - i   这样第一趟冒泡排序的时候,从下标第0位开始,到下标第7位结束,正好比完
        // 第二趟 从下标第0位开始,到下标第6位结束   随着趟数的增加,结束的下标位置逐渐减小
        for (j = 0; j < sz - i; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                int tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
    }
}

int main()
{
    int arr[] = {12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
    int i = 0;
    int sz = sizeof(arr) / sizeof(arr[0]);
    // 对arr进行排序,排成升序
    bubble_sort(arr, sz);
    for (i = 0; i < sz; i++)
    {
        printf("%d \n", arr[i]);
    }
}

.
.
.
.
.
.
.

posted @ 2023-09-16 16:12  tengyifan  阅读(91)  评论(0编辑  收藏  举报