剑指offer全集系列Java版本(2)

news2024/12/24 8:19:43

目录

反转链表

替换空格

二叉树

链表的中间结点

附录

StringBuffer类中常用的方法 


反转链表

反转链表_牛客题霸_牛客网 (nowcoder.com)icon-default.png?t=N7T8https://www.nowcoder.com/practice/75e878df47f24fdc9dc3e400ec6058ca?tpId=265&tqId=39226&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3Fpage%3D1%26tpId%3D13%26type%3D265&difficulty=undefined&judgeStatus=undefined&tags=&title=

解法1: 使用堆栈

        思路如下, 首先创建一个堆栈, 然后依次遍历链表, 将链表的结点依次存入堆栈, 然后新建一个链表然后依次弹出结点, 让后将此弹出的结点, 尾插到新链表的尾部

时间复杂度: O(n)
空间复杂度: O(n)

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @return ListNode类
     */
    public ListNode ReverseList (ListNode head) {
        if (head == null) {
            return null;
        }
        // write code here
        Stack<Integer> stack = new Stack<>();
        ListNode newHead = new ListNode(0);
        ListNode result = newHead;
        while(head != null) {
            stack.push(head.val);
            head = head.next;
        }
        while(!stack.isEmpty()) {
            newHead.val = stack.pop();
            if (stack.isEmpty()) {
                break;
            }
            ListNode tem = new ListNode(0);
            newHead.next = tem;
            newHead = newHead.next;
        }
        return result;

    }
}

 解法2: 依次遍历

        使用多指针的方法, 依次将结点的next赋值为他的前一个结点, 然后往后遍历.

时间复杂度: O(n)
空间复杂度: O(1)

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @return ListNode类
     */
    public ListNode ReverseList (ListNode head) {
        if (head == null) {
            return null;
        }
        if (head.next == null) {
            return head;
        }
        // write code here
        ListNode l = head;
        
        ListNode center = head.next;
        ListNode r = center.next;

        l.next = null;
        while (center != null) {
            center.next = l;
            l = center;
            center = r;
            if (r == null) {
                return l;
            }
            r = r.next;
        }
        return null;


    }
}

 解法3: 递归

        使用递归的方法来遍历这个集合, 这种方法类似于使用堆栈的方法 , 虽然代码少了很多, 但是代码的可读性缺不高, 非常锻炼玩家的思维能力.

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @return ListNode类
     */
    public ListNode ReverseList (ListNode head) {
        // write code here
        if (head == null || head.next == null) {
            return head;
        }
        ListNode next = head.next;
        ListNode reverse  = ReverseList(next);
        next.next = head;
        head.next = null;
        return reverse;
    }
}

        需要注意的是, 如果调用过多的递归, 会导致函数调用栈溢出的情况.

替换空格

        题目中给出的字符串为一个StringBuffer字符串, 他是线程安全的字符串, 同时也可以对其进行修改的字符串(我们知道java中String类是不能修改的) 

        在做题之前 , 我们首先应该去了解String类和StringBuffer, 和StringBuilder中提供了哪些方法供我们使用, 我将其整理在了后面的附录中, 可以点击目录查看.

我们有很多种实现的方法, 例如:

解法1: 新建一个StringBuffer字符串

        新建一个StringBuffer对象, 以此扫描str, 如果不是空格, 就直接追加字符到新的字符串中, 如果是空格, 就将%20追加到新的字符串中, 然后返回他的toString方法的返回值就行.

import java.util.*;
public class Solution {
    public String replaceSpace(StringBuffer str) {
    	StringBuffer strb = new StringBuffer();
        for(int i = 0; i < str.length(); i++) {
            char tem = str.charAt(i);
            if (tem == ' ') {
                strb.append("%20");
            } else {
                strb.append(tem);
            }
        }
        return strb.toString();
    }
}

  解法2: delete(deleteCharAt) + insert

        直接遍历str, 如果是空格就先将其删除然后, 再插入%20

import java.util.*;
public class Solution {
    public String replaceSpace(StringBuffer str) {
    	for (int i = 0; i < str.length(); i++) {
            char tem = str.charAt(i);
            if (tem == ' ') {
                str.deleteCharAt(i);
                str.insert(i,"%20");
            }
        }
        return str.toString();
    }
}


二叉树

        树是一种逻辑结构,同时也是一种分层结构,

其定义结构如下: 

  • 有且仅有一个特定的点可以做为根节点
  • 树的根节点是没有前驱的
  • 树的所有结点可以有0个或者是多个后继
  • 特殊的,我们将每个父亲最多只有两个孩子的树叫做二叉树

二叉树有什么特点?? 

 二叉树的结构代码定义:

#include<stdio.h>
#include<malloc.h>

typedef char ElementType;
typedef struct BNode {
	ElementType data;
	struct BNode* left;
	struct BNode* right;
}BNode,*BTree;

 辅助队列:

typedef struct tag {
	BiTree p;
	struct tag* next;
}tag_t,*ptag_t;

建树的过程:

#define _CRT_SECURE_NO_WARNINGS 1


#include<stdio.h>
#include<malloc.h>

typedef char ElementType;
typedef struct BNode {
	ElementType data;
	struct BNode* left;
	struct BNode* right;
}BNode,* BiTree;

typedef struct tag {
	BiTree p;
	struct tag* next;
}tag_t,*ptag_t;

int main() {
	BiTree pnew;   // 树的新的结点
	BiTree tree = NULL; // 树根
	ptag_t phead = NULL, ptail = NULL, listpnew = NULL, pcur = NULL;
	char c;
	while (scanf("%c", &c)) {
		if (c == '\n') {
			break;
		}
		pnew = (BiTree)calloc(1, sizeof(BNode));
		pnew->data = c;
		listpnew = (ptag_t)calloc(1, sizeof(tag_t));
		listpnew->p = pnew;

		if (NULL == tree) {
			tree = pnew;
			phead = listpnew;
			ptail = listpnew;
			pcur = listpnew;
		}
		else {
			ptail->next = listpnew;
			ptail = listpnew;
			if (pcur->p->left == NULL) {
				pcur->p->left = pnew;
			}
			else if (pcur->p->right == NULL	){
				pcur->p->right = pnew;
				pcur = pcur->next;
			}

		}
	}

	return 0;
}

        树是一种简单的数据结构, 面试中提到的树一般都是二叉树, 也就是一种特殊的树结构, 根节点没有父结点. ,每个结点有一到两个子节点, 树存在着好几种遍历方式, 一般有:

  • 前序遍历: 先访问根节点, 再访问左子节点, 然后再访问右子节点
  • 中序遍历: 先访问左子节点, 然后访问根节点, 随后访问右子节点
  • 后序遍历: 先访问左子节点, 然后访问右子节点, 最后访问根节点

前中后序遍历的实现(递归实现) :

前序遍历:

        以上这三种遍历方式的六种实现应该了如指掌

        接下来看这三个遍历的例子:

void preOrder(BiTree root) {
	if (root == NULL) {
		return;
	}
	printf("%c", root->data);
	preOrder(root->left);
	preOrder(root->right);
}

void inOrder(BiTree root) {
	if (root == NULL) {
		return;
	}
	inOrder(root->left);
	printf("%c", root->data);
	inOrder(root->right);
}

void lastOrder(BiTree root) {
	if (root == NULL) {
		return;
	}
	lastOrder(root->left);
	lastOrder(root->right);
	printf("%c", root->data);
}

  • 宽度优先遍历: 先访问第一层的结点, 在访问第二层的结点, 每一层就时从左到右以此访问.

广度优先遍历的代码:

广度优先遍历需要借助一个辅助队列, 如下:

void levelOrder(BiTree root) {
	SqQueue queue; // 辅助队列
	InitQueue(queue); // 初始化一个队列.
	EnQueue(queue, root);  // 将根节点首先放入队列
	while (!isEmpty(queue)) {
		BiTree tem;
		DeQueue(queue,tem);  // 出队一个元素.
		printf("%c", tem->data); // 
		if (tem->left != NULL) {  // 如果左孩子不为空, 就将左孩子入队
			EnQueue(queue, tem->left);
		}
		if (tem->right != NULL) { // 如果右孩子不为空, 就将右孩子入队
			EnQueue(queue, tem->right);
		}
	}
}

带权路径之和:

带权路径之和为每个叶子结点的深度(路径长度)和其权值的乘积..

#define _CRT_SECURE_NO_WARNINGS 1


#include<stdio.h>
#include<malloc.h>

typedef struct BNode {
	char data;
	struct BNode* left;
	struct BNode* right;
}BNode, * BiTree;


typedef struct tag {
	BiTree p;
	struct tag* next;
}tag_t, * ptag_t;


int wpl = 0;
int wpl_preOrder(BiTree root, int deep) {
	if (root == NULL) {
		return;
	}
	if (root->left == NULL && root->right == NULL) {
		wpl += deep * (root->data);
	}
	printf("%c", root->data);
	wpl_preOrder(root->left, deep + 1);
	wpl_preOrder(root->right, deep +1);
	return wpl;
}

int WPL(BiTree root) {
	wpl = 0;
	return wpl_preOrder(root, 0);
}

链表的中间结点

题目链接: 

链表的中间结点_牛客题霸_牛客网 (nowcoder.com)icon-default.png?t=N7T8https://www.nowcoder.com/practice/d0e727d0d9fb4a9b9ff2df99f9bfdd00?tpId=196&tqId=40336&ru=/exam/oj

实例 

        通过例子可以知道, 加入链表有技术个数, 那么中间结点就为中间那个数, 如果为偶数个, 那么中间结点就有两个, 例如{1,2,3,4}, 中间结点为2和3, 但是我们认为中间结点为3, 于是返回3的地址.

        思路:  使用快慢指针 定义连个指针, 他们刚开始都指向头结点, 分别为slow指针和fast指针, 定义: slow指针每次只走一个结点, fast指针每次走两个结点.

经过第一次slow走一步, fast走两步:

然后再走一次, 结果如下:

        此时, fast指向NULL, slow刚好指向了中间这个结点

假设现在有奇数个结点, 如下:

        现在slow走一步, fast走两步

第一次:

 第二次:

        此时, fast的next为空时, slow指向中间结点

总结, 上面两种情况, 无论是奇数个结点还是偶数个结点, 只要fast的next为NULL或者fast本身为NULL的时候, slow就会指向中间结点. 

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param head ListNode类 
 * @return ListNode类
 */
struct ListNode* middleNode(struct ListNode* head ) {
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while(fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}

附录

StringBuffer类中常用的方法 

    • Modifier and TypeMethod and Description
      StringBufferappend(boolean b)

      boolean参数的字符串表示附加到序列中。

      StringBufferappend(char c)

      char参数的字符串表示附加到此序列。

      StringBufferappend(char[] str)

      char数组参数的字符串表示附加到此序列。

      StringBufferappend(char[] str, int offset, int len)

      char数组参数的子阵列的字符串表示附加到此序列。

      StringBufferappend(CharSequence s)

      追加指定的 CharSequence到这个序列。

      StringBufferappend(CharSequence s, int start, int end)

      追加指定的序列 CharSequence到这个序列。

      StringBufferappend(double d)

      double参数的字符串表示附加到此序列。

      StringBufferappend(float f)

      float参数的字符串表示附加到此序列。

      StringBufferappend(int i)

      int参数的字符串表示附加到此序列。

      StringBufferappend(long lng)

      long参数的字符串表示附加到此序列。

      StringBufferappend(Object obj)

      追加 Object参数的字符串表示。

      StringBufferappend(String str)

      将指定的字符串附加到此字符序列。

      StringBufferappend(StringBuffer sb)

      将指定 StringBuffer这个序列。

      StringBufferappendCodePoint(int codePoint)

      codePoint参数的字符串表示法附加到此序列。

      intcapacity()

      返回当前容量。

      charcharAt(int index)

      返回 char在指定索引在这个序列值。

      intcodePointAt(int index)

      返回指定索引处的字符(Unicode代码点)。

      intcodePointBefore(int index)

      返回指定索引之前的字符(Unicode代码点)。

      intcodePointCount(int beginIndex, int endIndex)

      返回此序列指定文本范围内的Unicode代码点数。

      StringBufferdelete(int start, int end)

      删除此序列的子字符串中的字符。

      StringBufferdeleteCharAt(int index)

      删除 char在这个序列中的指定位置。

      voidensureCapacity(int minimumCapacity)

      确保容量至少等于规定的最小值。

      voidgetChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)

      字符从该序列复制到目标字符数组 dst

      intindexOf(String str)

      返回指定子字符串第一次出现的字符串内的索引。

      intindexOf(String str, int fromIndex)

      返回指定子串的第一次出现的字符串中的索引,从指定的索引开始。

      StringBufferinsert(int offset, boolean b)

      在此序列中插入 boolean参数的字符串表示形式。

      StringBufferinsert(int offset, char c)

      在此序列中插入 char参数的字符串表示形式。

      StringBufferinsert(int offset, char[] str)

      在此序列中插入 char数组参数的字符串表示形式。

      StringBufferinsert(int index, char[] str, int offset, int len)

      在此序列中插入 str数组参数的子阵列的字符串表示形式。

      StringBufferinsert(int dstOffset, CharSequence s)

      将指定的 CharSequence这个序列。

      StringBufferinsert(int dstOffset, CharSequence s, int start, int end)

      将指定的子序列 CharSequence这个序列。

      StringBufferinsert(int offset, double d)

      在此序列中插入 double参数的字符串表示形式。

      StringBufferinsert(int offset, float f)

      在此序列中插入 float参数的字符串表示形式。

      StringBufferinsert(int offset, int i)

      将第二个 int参数的字符串表示插入到此序列中。

      StringBufferinsert(int offset, long l)

      在此序列中插入 long参数的字符串表示形式。

      StringBufferinsert(int offset, Object obj)

      Object参数的字符串表示插入到此字符序列中。

      StringBufferinsert(int offset, String str)

      将字符串插入到此字符序列中。

      intlastIndexOf(String str)

      返回指定子字符串最右边出现的字符串内的索引。

      intlastIndexOf(String str, int fromIndex)

      返回指定子字符串最后一次出现的字符串中的索引。

      intlength()

      返回长度(字符数)。

      intoffsetByCodePoints(int index, int codePointOffset)

      返回此序列中与 indexcodePointOffset代码点偏移的索引。

      StringBufferreplace(int start, int end, String str)

      用指定的String中的字符替换此序列的子字符串中的 String

      StringBufferreverse()

      导致该字符序列被序列的相反代替。

      voidsetCharAt(int index, char ch)

      指定索引处的字符设置为 ch

      voidsetLength(int newLength)

      设置字符序列的长度。

      CharSequencesubSequence(int start, int end)

      返回一个新的字符序列,该序列是该序列的子序列。

      Stringsubstring(int start)

      返回一个新的 String ,其中包含此字符序列中当前包含的字符的子序列。

      Stringsubstring(int start, int end)

      返回一个新的 String ,其中包含此序列中当前包含的字符的子序列。

      StringtoString()

      返回表示此顺序中的数据的字符串。

      voidtrimToSize()

      尝试减少用于字符序列的存储。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1181675.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

时序预测 | MATLAB实现基于LSSVM-Adaboost最小二乘支持向量机结合AdaBoost时间序列预测

时序预测 | MATLAB实现基于LSSVM-Adaboost最小二乘支持向量机结合AdaBoost时间序列预测 目录 时序预测 | MATLAB实现基于LSSVM-Adaboost最小二乘支持向量机结合AdaBoost时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现基于LSSVM-Adaboos…

Spring Cloud学习(一)【SpringCloud介绍/服务远程调用】

文章目录 单体架构分布式架构微服务微服务技术对比Spring Cloud 介绍服务拆分及远程调用 单体架构 单体架构&#xff1a; 将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部署。 优点&#xff1a; 架构简单部署成本低 缺点&#xff1a; 耦合度高 分布式架构 …

小程序day04

目标 自定义组件 创建组件 引用组件 局部引用 全局引用 组件的函数定义到metods节点中&#xff0c;梦回vue2. 样式 数据&#xff0c;方法&#xff0c;属性 下划线开头的称为自定义方法&#xff0c;非下划线开头的都是事件处理函数。 神特么&#xff0c;this.datathis.pro…

【计算系统】分布式训练:DDP单机多卡并行实战

分布式训练&#xff1a;DDP单机多卡并行 1. 分布式训练总览1.1 并行方式1.2 PyTorch中数据并行方法1.3 训练原理1. DataParallel(DP)训练原理2. DistributedDataParallel(DDP)多卡训练的原理 2. PyTorch分布式代码实战2.1 不使用DDP和混合精度加速的代码2.2 使用DDP对代码改造后…

2021年06月 Python(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试&#xff08;1~6级&#xff09;全部真题・点这里 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 对自然数1至n求和&#xff0c;如果将递推式f(n)f(n-1)n(n>1)转化成递归函数&#xff0c;则递归出口是&#xff1f; …

自动出价下机制设计系列 (二) : 面向私有约束的激励兼容机制设计

本文作者&#xff1a;真柏、妙临 欢迎关注&#xff1a;阿里妈妈技术公众号>> 导读&#xff1a;这篇是阿里妈妈在自动出价下机制设计系列的第二篇工作&#xff08;&#x1f517; 第一篇&#xff1a;面向异质目标函数广告主的拍卖机制设计&#xff09;。在自动出价中&…

猫罐头哪家好?5款良心性价比的猫罐头推荐!

在我们日常的宠物喂养中&#xff0c;猫罐头已经成为了许多猫奴们的必备利器。但面对五花八门的猫罐头品牌&#xff0c;如何为你的猫咪挑选一个既合适又满意的猫罐头呢&#xff1f;作为一家宠物店的老江湖&#xff0c;我已经在宠物行业摸爬滚打了七年&#xff0c;店里的猫儿队伍…

数据库的基础增删查改操作(二)

TOC 一.条件查询的练习题 – 查询英语不及格的同学及英语成绩 ( < 60 ) – 查询语文成绩好于英语成绩的同学 查询语文成绩高于60,英语成绩低于60 查询li开头的学生姓名 1.and与or 查询语文成绩大于80分&#xff0c;且英语成绩大于80分的同学 SELECT * FROM exam_result W…

Anaconda如何创建一个环境

activate env_name 激活环境&#xff0c;env_name&#xff1a;环境名 deactivate env_name 激活环境 conda list …

java八股文(mysql篇)

什么是关系型数据库&#xff1f; 其是建立在关系模型基础上的一种数据库&#xff0c;这种关系分为&#xff1a;一对一&#xff0c;一对多&#xff0c;多对多。 我们的数据存放在表中&#xff0c;在表中会有一至多个字段&#xff0c;一行就是一条数据。 mysql有哪些字段呢&…

pg安装pgagent插件以创建job

一 下载 官方下载地址Download 二 安装 2.1 安装cmake 执行cmake -version查看版本&#xff0c;如果能看到版本信息&#xff0c;就不用重复安装了。 cd /usr/local/ tar xvf cmake-3.16.5-Linux-x86_64.tar.gzcd cmake-3.16.5-Linux-x86_64/binvi /etc/profile 在最后新增…

哇,膜拜,师父竟然懂HARAKIRI的意思(附Linux常用命令)

哇&#xff0c;膜拜&#xff0c;师父竟然懂HARAKIRI的意思 我在看服务器日志的时候&#xff0c;发现有好几行开头都写着HARAKIRI 还以为是什么机制&#xff0c;就去问了问AI&#xff0c;结果它也不懂&#xff0c;百度也没查到 就去问师父&#xff0c;他一下就说出&#xff0c…

Kubernetes - pod详解

Pod基础概念&#xff1a; Pod是kubernetes中最小的资源管理组件&#xff0c;Pod也是最小化运行容器化应用的资源对象。一个Pod代表着集群中运行的一个进程。kubernetes中其他大多数组件都是围绕着Pod来进行支撑和扩展Pod功能的&#xff0c;例如&#xff0c;用于管理Pod运行的S…

动手学Matplotlib画图,Matplotlib 是一个非常强大的 Python 画图工具。【Matplotlib学习笔记】

一、第一章 1.基本用法 import matplotlib.pyplot as plt import numpy as npx np.linspace(-1,1,50) y 2*x 1 plt.plot(x,y) plt.show()2.figure图像 import matplotlib.pyplot as plt import numpy as npx np.linspace(-1,1,50) y1 2*x 1 y2 x**2 plt.figure() plt…

6.ELK之Elasticsearch嵌套(Nested)类型

0、前言 在Elasticsearch实际应用中经常会遇到嵌套文档的情况&#xff0c;而且会有“对象数组彼此独立地进行索引和查询的诉求”。在ES中这种嵌套文档称为父子文档&#xff0c;父子文档“彼此独立地进行查询”至少有以下两种方式&#xff1a; 1&#xff09;父子文档。在ES的5.…

基于人工蜂鸟算法的无人机航迹规划-附代码

基于人工蜂鸟算法的无人机航迹规划 文章目录 基于人工蜂鸟算法的无人机航迹规划1.人工蜂鸟搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用人工蜂鸟算法来优化无人机航迹规划。 …

【kubernetes】k8s组件

文章目录 1、概述2、控制平面组件&#xff08;Control Plane Components&#xff09;2.1 kube-apiserver2.2 etcd2.3 kube-scheduler2.4 kube-controller-manager2.5 cloud-controller-manager 3、Node组件3.1 kubelet3.2 kube-proxy3.3 容器运行时&#xff08;Container Runti…

基础算法-回溯算法-案例

现象&#xff1a; 基础算法-回溯算法-案例 基础算法-回溯算法从不同角度出发 去寻找答案 找到答案或者走不通了(根据需求:找一个答案还是列举全部答案) 则回溯返回继续从下一条路出发 去寻找答案, 一直到走完 常见案例&#xff1a; 案例一&#xff1a; 通过输入一个不重复数…

找到【SVM】中最优的惩罚项系数C

因为本来SVM是想找到间隔最大的分割面&#xff0c;所以C越大&#xff0c;SVC会选择边际更小的&#xff0c;能够更好的分类所有训练点的决策边界&#xff0c;不过模型的训练时间也会越长。如果C的设定值较小&#xff0c;那SVC会尽量最大化边界&#xff0c;决策功能会更简单&…

4.求1000以内的所有完数

#include<stdio.h> // 完数&#xff1a;一个数的所有的真因子 (即除了自身以外的约数)的和&#xff0c;恰好等于它自身 // 1 不是完数 // 4的因子&#xff1a;1 2 4 除了本身 4 不等于 1&#xff0b;2 所以4不是完数void fun(void){int sum,i,j;for(i2;i<1000;i)…